Difference between revisions of "Defining CPU Models (as of M5 2.0 - beta 3)"

From gem5
Jump to: navigation, search
(Port C++ Code for MyCPU)
(Testing MyCPU)
 
(25 intermediate revisions by the same user not shown)
Line 8: Line 8:
  
  
For example, one could copy the files from the 'm5/src/cpu/simple' and place them in their own CPU directory: m5/src/cpu/mycpu.
+
For this example, we'll just copy the files from the 'm5/src/cpu/simple' and place them in our own CPU directory: m5/src/cpu/mycpu.
 
<pre>
 
<pre>
 
me@mymachine:~/m5$ cd src/cpu  
 
me@mymachine:~/m5$ cd src/cpu  
Line 32: Line 32:
 
</pre>
 
</pre>
  
 +
 +
The last thing you need to do is edit your mycpu.cc file to contain a reference to the 'cpu/mycpu/mycpu.hh" header file instead of the 'cpu/simple/atomic.hh'
 +
file:
 +
<pre>
 +
#include "arch/locked_mem.hh"
 +
...
 +
#include "cpu/mycpu/mycpu.hh"
 +
...
 +
</pre>
  
 
NOTE: The AtomicSimpleCPU is really just based off the BaseSimpleCPU (src/cpu/simple/base.hh) so your new CPU Model MyCPU is really a derivation off of
 
NOTE: The AtomicSimpleCPU is really just based off the BaseSimpleCPU (src/cpu/simple/base.hh) so your new CPU Model MyCPU is really a derivation off of
this CPU model. Additionally, the BaseSimpleCPU model is derived from the BaseCPU (src/cpu/base.hh) so you can see that M5 is heavily object oriented.
+
this CPU model. Additionally, the BaseSimpleCPU model is derived from the BaseCPU (src/cpu/base.hh). As you can see, M5 is heavily object oriented.
  
 
== Making M5 Recognize MyCPU ==
 
== Making M5 Recognize MyCPU ==
 
Now that you've created a separate directory and files for your MyCPU code (i.e. m5/src/cpu/mycpu), there are a couple files that need to be updated so that M5 can recognize M5 as a build option:
 
Now that you've created a separate directory and files for your MyCPU code (i.e. m5/src/cpu/mycpu), there are a couple files that need to be updated so that M5 can recognize M5 as a build option:
* ''m5/SConstruct'': Add the name of your CPU model (MyCPU) to the 'ALL_CPU_LIST'
+
*''m5/src/cpu/mycpu/SConscript'': Edit the SConscript for your CPU model and add the relevant files that need to be built in here. Your file should only contain this code:
 
<pre>
 
<pre>
...
+
Import('*')
# Define the universe of supported CPU models
+
 
env['ALL_CPU_LIST'] = ['AtomicSimpleCPU', 'TimingSimpleCPU',
+
need_simple_base = False
                      'FullCPU', 'O3CPU','MixieCPU',
+
if 'MyCPU' in env['CPU_MODELS']:
                      'OzoneCPU', 'MyCPU']
+
    need_simple_base = True
... ..
+
    Source('mycpu.cc')
 +
 
 +
if need_simple_base:
 +
    Source('base.cc')
 
</pre>
 
</pre>
  
*''m5/src/cpu/SConscript'': Add your CPU model and the relevant files that need to be built in here
+
*''m5/src/cpu/mycpu/SConsopts'': Edit the SConscript for your CPU model and add the relevant files that need to be built in here. Your file should only contain this code:
 
<pre>
 
<pre>
...
+
Import('*')
if 'AtomicSimpleCPU' in env['CPU_MODELS']:
 
    need_simple_base = True
 
    sources += Split('simple/atomic.cc')
 
  
if 'MyCPU' in env['CPU_MODELS']:
+
all_cpu_list.append('MyCPU')
    need_simple_base = True
+
default_cpus.append('MyCPU')
    sources += Split('simple/mycpu.cc')
 
...
 
 
</pre>
 
</pre>
  
Line 85: Line 92:
 
</pre>
 
</pre>
  
*''m5/src/python/objects/MyCPU.py'': Create a python file (e.g. MyCPU.py) so that your CPU can be recognized as a simulation object. For this example, we will just copy the SimpleCPU.py file and then
+
*''m5/src/python/objects/MyCPU.py'': Create a python file (e.g. MyCPU.py) so that your CPU can be recognized as a simulation object. For this example, we will just use the same code in the SimpleCPU.py file but replace the name 'AtomicSimpleCPU' with 'MyCPU'.
replace the name 'AtomicSimpleCPU' with 'MyCPU'.
 
  
So first copy the file:
+
Create a file named MyCPU.py file to represent your CPU Model:
 
<pre>
 
<pre>
 
+
me@mymachine:~/m5/src/cpu/mycpu$cd ~/m5/src/python/objects
cp SimpleCPU.py MyCPU.py
+
me@mymachine:~/m5/src/python/objects$emacs MyCPU.py&
 
</pre>
 
</pre>
  
Then edit the file (NOTE: Make sure you delete the python block for 'TimingSimpleCPU'):
+
Add this to your file:
 
<pre>
 
<pre>
 +
from m5.params import *
 +
from m5 import build_env
 +
from BaseCPU import BaseCPU
 +
 
class MyCPU(BaseCPU):
 
class MyCPU(BaseCPU):
 
     type = 'MyCPU'
 
     type = 'MyCPU'
Line 109: Line 119:
 
</pre>
 
</pre>
  
*''m5/src/python/objects/__init__.py'': Add the base name of your python file into the 'file_bases' list.
+
*''m5/src/python/SConscript'': Add the name of your Python Object Configuration File into the python SConscript...
 
<pre>
 
<pre>
# specify base part of all object file names
+
...
file_bases = ['AlphaConsole',
+
SimObject('m5/objects/MyCPU.py')
              'O3CPU',
+
...
              'AlphaTLB',
+
</pre>
  
 +
 +
 +
== Building MyCPU ==
 +
Navigate to the M5 top-level directory and build your model:
 +
<pre>
 +
me@mymachine:~/m5/src/python/objects$cd ~/m5
 +
me@mymachine:~/m5$scons build/MIPS_SE/m5.debug CPU_MODELS=MyCPU
 +
scons: Reading SConscript files ...
 +
Checking for C header file Python.h... (cached) yes
 
...
 
...
      'MyCPU',
+
Building in /y/ksewell/research/m5-sim/newmem-clean/build/MIPS_SE
              'OzoneCPU',
+
Options file /y/ksewell/research/m5-sim/newmem-clean/build/options/MIPS_SE not found,
 +
  using defaults in build_opts/MIPS_SE
 +
Compiling in MIPS_SE with MySQL support.
 +
scons: done reading SConscript files.
 +
scons: Building targets ...
 +
make_hh(["build/MIPS_SE/base/traceflags.hh"], ["build/MIPS_SE/base/traceflags.py"])
 +
Generating switch header build/MIPS_SE/arch/interrupts.hh
 +
Generating switch header build/MIPS_SE/arch/isa_traits.hh
 +
Defining FULL_SYSTEM as 0 in build/MIPS_SE/config/full_system.hh.
 +
Generating switch header build/MIPS_SE/arch/regfile.hh
 +
Generating switch header build/MIPS_SE/arch/types.hh
 +
Defining NO_FAST_ALLOC as 0 in build/MIPS_SE/config/no_fast_alloc.hh.
 
...
 
...
              'Uart']
+
g++ -o build/MIPS_SE/arch/mips/faults.do -c -pipe -fno-strict-aliasing -Wall -Wno-sign-compare -Werror -Wundef -ggdb3 -DTHE_ISA=MIPS_ISA -DDEBUG -DTRACING_ON=1 -Iext/dnet
 +
-I/usr/include/python2.4 -Ibuild/libelf/include -I/usr/include/mysql -Ibuild/MIPS_SE build/MIPS_SE/arch/mips/faults.cc
 +
g++ -o build/MIPS_SE/arch/mips/isa_traits.do -c -pipe -fno-strict-aliasing -Wall -Wno-sign-compare -Werror -Wundef -ggdb3 -DTHE_ISA=MIPS_ISA -DDEBUG -DTRACING_ON=1 -Iext/dnet
 +
-I/usr/include/python2.4 -Ibuild/libelf/include -I/usr/include/mysql -Ibuild/MIPS_SE build/MIPS_SE/arch/mips/isa_traits.cc
 +
g++ -o build/MIPS_SE/arch/mips/utility.do -c -pipe -fno-strict-aliasing -Wall -Wno-sign-compare -Werror -Wundef -ggdb3 -DTHE_ISA=MIPS_ISA -DDEBUG -DTRACING_ON=1 -Iext/dnet
 +
-I/usr/include/python2.4 -Ibuild/libelf/include -I/usr/include/mysql -Ibuild/MIPS_SE build/MIPS_SE/arch/mips/utility.cc
 +
...
 +
cat build/MIPS_SE/m5.debug.bin build/MIPS_SE/m5py.zip > build/MIPS_SE/m5.debug
 +
chmod +x build/MIPS_SE/m5.debug
 +
scons: done building targets.
 +
</pre>
  
 +
If you are compiling on a dual-core CPU, use this command-line to speed-up the compilation:
 +
<pre>
 +
scons -j2 build/MIPS_SE/m5.debug CPU_MODELS=MyCPU
 
</pre>
 
</pre>
  
== Building MyCPU ==
+
 
'''Now build your model:'''
+
== Creating Configuration Scripts for MyCPU ==
 +
Now that you have a M5 binary built for use with the MIPS Architecture in a M5, MyCPU Model, you are almost ready to simulate. Note that the standard M5 command line requires taht your provide
 +
at least a configuration script for the M5 binary to use.
 +
 
 +
The easiest way to get up and running is to use the sample Syscall-Emulation script: ''configs/example/se.py''.
 +
 
 +
You'll note that line 9 of the se.py Python script imports the details of what type of Simulation will be run (e.g. what CPU Model?) from the Simulation.py file found here:
 +
m5/configs/common/Simulation.py. And then, the Simulation.py file imports it's CPU Model options from the Options.py file in the same directory. Edit those two files and
 +
your M5 binary will be ready to simulate.
 +
 
 +
*''m5/configs/common/Options.py'': Add a option for your model in this file...
 
<pre>
 
<pre>
scons build/ALPHA_SE/m5.debug CPU_MODELS=MyCPU
+
...
 +
parser.add_option("--my_cpu", action="store_true", help="Use MyCPU Model")
 +
...
 
</pre>
 
</pre>
If you have dual-core CPU use this to speed-up the compilation:
+
 
 +
 
 +
*''m5/configs/common/Simulation.py'': Edit the Simulation script to recognize your model as a CPU class. After your edits, the setCPUClass function should look like this:
 
<pre>
 
<pre>
scons -j2 build/ALPHA_SE/m5.debug CPU_MODELS=MyCPU
+
...
</pre>
+
def setCPUClass(options):
 +
   
 +
    atomic = False
 +
    if options.timing:
 +
        TmpClass = TimingSimpleCPU
 +
    elif options.my_cpu:
 +
TmpClass = MyCPU
 +
        atomic = True
 +
    elif options.detailed:
 +
        if not options.caches:
 +
            print "O3 CPU must be used with caches"
 +
            sys.exit(1)
 +
        TmpClass = DerivO3CPU
 +
    else:
 +
        TmpClass = AtomicSimpleCPU
 +
        atomic = True
 +
       
 +
    CPUClass = None
 +
    test_mem_mode = 'atomic'
  
== Creating Configuration Options For MyCPU ==
+
    if not atomic:  
'''Create and edit configuration files for your model:'''
+
        if options.checkpoint_restore:
*m5/configs/test/MyCPUConfig.py: Define a configuration class w/corresponding parameters for your model. Look to 'FullO3Config.py' in the same directory for an example of how to do this.
+
            CPUClass = TmpClass
*m5/configs/test/test.py: Import your model's configuration at the top of the file (i.e. 'import MyCPUConfig') and add in a parser option for your CPU model (e.g. '--my_cpu').
+
            TmpClass = AtomicSimpleCPU
 +
        else:
 +
            test_mem_mode = 'timing'
  
 +
    return (TmpClass, test_mem_mode, CPUClass)
 +
...
 +
</pre>
  
 
== Testing MyCPU ==
 
== Testing MyCPU ==
'''Test your model:'''
+
Once you've edited the configuration scripts, you can run a M5 simulation from the top level directory with this command line:
 
<pre>
 
<pre>
build/ALPHA_SE/m5.debug configs/example/se.py --my_cpu --cmd=<bin_path>
+
me@mymachine:~/m5$build/MIPS_SE/m5.debug configs/example/se.py --my_cpu --cmd=tests/test-progs/hello/bin/mips/linux/hello
 
</pre>
 
</pre>
 +
 +
NOTE: This binary path refers to the m5/tests directory.
 +
 +
== Summary ==
 +
So the above "tutorial" showed you how to build your own CPU model in M5. Now, it's up to you to customize the CPU Model as you like and do your experiments! Good luck!

Latest revision as of 19:47, 23 May 2007

Overview

First, make sure you have basic understanding of how the CPU models function within the M5 framework. A good start is the CPU Models page.

This brief tutorial will show you how to create a custom CPU model called 'MyCPU', which will just be a renamed version of the AtomicSimpleCPU. After you learn how to compile and build 'MyCPU', then you have the liberty to edit the 'MyCPU' code at your heart's content without worrying about breaking any existing M5 CPU Models.

Port C++ Code for MyCPU

The easiest way is to derive a new C++ class of your CPU Model from M5 CPU Models that are already defined and the easiest model to start with is the 'AtomicSimpleCPU' located in the 'm5/src/cpu/simple' directory.


For this example, we'll just copy the files from the 'm5/src/cpu/simple' and place them in our own CPU directory: m5/src/cpu/mycpu.

me@mymachine:~/m5$ cd src/cpu 
me@mymachine:~/m5/src/cpu$ mkdir mycpu 
me@mymachine:~/m5/src/cpu$ cp -r simple/* mycpu


Now check the mycpu directory to make sure you've copied the files successfully:

me@mymachine:~/m5/src/cpu$ cd mycpu 
me@mymachine:~/m5/src/cpu/mycpu$ ls
atomic.cc  atomic.hh  base.cc  base.hh  timing.cc  timing.hh


Since we want to change 'AtomicSimpleCPU' to 'MyCPU' we will just replace all the names in the atomic.* files and name them mycpu.* files:

me@mymachine:~/m5/src/cpu/mycpu$ perl -pe s/AtomicSimpleCPU/MyCPU/g atomic.hh > mycpu.hh
me@mymachine:~/m5/src/cpu/mycpu$ perl -pe s/AtomicSimpleCPU/MyCPU/g atomic.cc > mycpu.cc
me@mymachine:~/m5/src/cpu/mycpu$ ls
atomic.cc  atomic.hh  base.cc  base.hh  mycpu.hh mycpu.cc timing.cc  timing.hh


The last thing you need to do is edit your mycpu.cc file to contain a reference to the 'cpu/mycpu/mycpu.hh" header file instead of the 'cpu/simple/atomic.hh' file:

#include "arch/locked_mem.hh"
...
#include "cpu/mycpu/mycpu.hh"
...

NOTE: The AtomicSimpleCPU is really just based off the BaseSimpleCPU (src/cpu/simple/base.hh) so your new CPU Model MyCPU is really a derivation off of this CPU model. Additionally, the BaseSimpleCPU model is derived from the BaseCPU (src/cpu/base.hh). As you can see, M5 is heavily object oriented.

Making M5 Recognize MyCPU

Now that you've created a separate directory and files for your MyCPU code (i.e. m5/src/cpu/mycpu), there are a couple files that need to be updated so that M5 can recognize M5 as a build option:

  • m5/src/cpu/mycpu/SConscript: Edit the SConscript for your CPU model and add the relevant files that need to be built in here. Your file should only contain this code:
Import('*')

need_simple_base = False
if 'MyCPU' in env['CPU_MODELS']:
    need_simple_base = True
    Source('mycpu.cc')

if need_simple_base:
    Source('base.cc')
  • m5/src/cpu/mycpu/SConsopts: Edit the SConscript for your CPU model and add the relevant files that need to be built in here. Your file should only contain this code:
Import('*')

all_cpu_list.append('MyCPU')
default_cpus.append('MyCPU')
  • m5/src/cpu/static_inst.hh: Put a forward class declaration of your model in here
...
class CheckerCPU;
class FastCPU;
class AtomicSimpleCPU;
class TimingSimpleCPU;
class InorderCPU;
class MyCPU;
...
  • m5/src/cpu/cpu_models.py: Add in CPU Model-specific information for the ISA Parser. The ISA Parser will use this when referring to the "Execution Context" for executing instructions. For instance, the AtomicSimpleCPU's instructions get all of their information from the actual CPU (since it's a 1 CPI machine). Thus, instructions only need to know the current state or "Execution Context" of the 'AtomicSimpleCPU' object. However, the instructions in a O3CPU needed to know the register values (& other state) only known to that current instruction so it's "Execution Context" is the O3DynInst object. (check out the ISA Description Language documentation page for more details)
...
CpuModel('AtomicSimpleCPU', 'atomic_simple_cpu_exec.cc',
         '#include "cpu/simple/atomic.hh"',
         { 'CPU_exec_context': 'AtomicSimpleCPU' })
CpuModel('MyCPU', 'mycpu_exec.cc',
         '#include "cpu/mycpu/mycpu.hh"',
         { 'CPU_exec_context': 'MyCPU' })
...
  • m5/src/python/objects/MyCPU.py: Create a python file (e.g. MyCPU.py) so that your CPU can be recognized as a simulation object. For this example, we will just use the same code in the SimpleCPU.py file but replace the name 'AtomicSimpleCPU' with 'MyCPU'.

Create a file named MyCPU.py file to represent your CPU Model:

me@mymachine:~/m5/src/cpu/mycpu$cd ~/m5/src/python/objects
me@mymachine:~/m5/src/python/objects$emacs MyCPU.py&

Add this to your file:

from m5.params import *
from m5 import build_env
from BaseCPU import BaseCPU

class MyCPU(BaseCPU):
    type = 'MyCPU'
    width = Param.Int(1, "CPU width")
    simulate_stalls = Param.Bool(False, "Simulate cache stall cycles")
    function_trace = Param.Bool(False, "Enable function trace")
    function_trace_start = Param.Tick(0, "Cycle to start function trace")
    if build_env['FULL_SYSTEM']:
        profile = Param.Latency('0ns', "trace the kernel stack")
    icache_port = Port("Instruction Port")
    dcache_port = Port("Data Port")
    _mem_ports = ['icache_port', 'dcache_port']
  • m5/src/python/SConscript: Add the name of your Python Object Configuration File into the python SConscript...
...
SimObject('m5/objects/MyCPU.py')
...


Building MyCPU

Navigate to the M5 top-level directory and build your model:

me@mymachine:~/m5/src/python/objects$cd ~/m5
me@mymachine:~/m5$scons build/MIPS_SE/m5.debug CPU_MODELS=MyCPU
scons: Reading SConscript files ...
Checking for C header file Python.h... (cached) yes
...
Building in /y/ksewell/research/m5-sim/newmem-clean/build/MIPS_SE
Options file /y/ksewell/research/m5-sim/newmem-clean/build/options/MIPS_SE not found,
  using defaults in build_opts/MIPS_SE
Compiling in MIPS_SE with MySQL support.
scons: done reading SConscript files.
scons: Building targets ...
make_hh(["build/MIPS_SE/base/traceflags.hh"], ["build/MIPS_SE/base/traceflags.py"])
Generating switch header build/MIPS_SE/arch/interrupts.hh
Generating switch header build/MIPS_SE/arch/isa_traits.hh
Defining FULL_SYSTEM as 0 in build/MIPS_SE/config/full_system.hh.
Generating switch header build/MIPS_SE/arch/regfile.hh
Generating switch header build/MIPS_SE/arch/types.hh
Defining NO_FAST_ALLOC as 0 in build/MIPS_SE/config/no_fast_alloc.hh.
...
g++ -o build/MIPS_SE/arch/mips/faults.do -c -pipe -fno-strict-aliasing -Wall -Wno-sign-compare -Werror -Wundef -ggdb3 -DTHE_ISA=MIPS_ISA -DDEBUG -DTRACING_ON=1 -Iext/dnet 
-I/usr/include/python2.4 -Ibuild/libelf/include -I/usr/include/mysql -Ibuild/MIPS_SE build/MIPS_SE/arch/mips/faults.cc
g++ -o build/MIPS_SE/arch/mips/isa_traits.do -c -pipe -fno-strict-aliasing -Wall -Wno-sign-compare -Werror -Wundef -ggdb3 -DTHE_ISA=MIPS_ISA -DDEBUG -DTRACING_ON=1 -Iext/dnet
 -I/usr/include/python2.4 -Ibuild/libelf/include -I/usr/include/mysql -Ibuild/MIPS_SE build/MIPS_SE/arch/mips/isa_traits.cc
g++ -o build/MIPS_SE/arch/mips/utility.do -c -pipe -fno-strict-aliasing -Wall -Wno-sign-compare -Werror -Wundef -ggdb3 -DTHE_ISA=MIPS_ISA -DDEBUG -DTRACING_ON=1 -Iext/dnet 
-I/usr/include/python2.4 -Ibuild/libelf/include -I/usr/include/mysql -Ibuild/MIPS_SE build/MIPS_SE/arch/mips/utility.cc
...
cat build/MIPS_SE/m5.debug.bin build/MIPS_SE/m5py.zip > build/MIPS_SE/m5.debug
chmod +x build/MIPS_SE/m5.debug
scons: done building targets.

If you are compiling on a dual-core CPU, use this command-line to speed-up the compilation:

scons -j2 build/MIPS_SE/m5.debug CPU_MODELS=MyCPU


Creating Configuration Scripts for MyCPU

Now that you have a M5 binary built for use with the MIPS Architecture in a M5, MyCPU Model, you are almost ready to simulate. Note that the standard M5 command line requires taht your provide at least a configuration script for the M5 binary to use.

The easiest way to get up and running is to use the sample Syscall-Emulation script: configs/example/se.py.

You'll note that line 9 of the se.py Python script imports the details of what type of Simulation will be run (e.g. what CPU Model?) from the Simulation.py file found here: m5/configs/common/Simulation.py. And then, the Simulation.py file imports it's CPU Model options from the Options.py file in the same directory. Edit those two files and your M5 binary will be ready to simulate.

  • m5/configs/common/Options.py: Add a option for your model in this file...
...
parser.add_option("--my_cpu", action="store_true", help="Use MyCPU Model")
...


  • m5/configs/common/Simulation.py: Edit the Simulation script to recognize your model as a CPU class. After your edits, the setCPUClass function should look like this:
...
def setCPUClass(options):
    
    atomic = False
    if options.timing:
        TmpClass = TimingSimpleCPU
    elif options.my_cpu:
	TmpClass = MyCPU
        atomic = True
    elif options.detailed:
        if not options.caches:
            print "O3 CPU must be used with caches"
            sys.exit(1)
        TmpClass = DerivO3CPU
    else:
        TmpClass = AtomicSimpleCPU
        atomic = True
        
    CPUClass = None
    test_mem_mode = 'atomic'

    if not atomic:    
        if options.checkpoint_restore:
            CPUClass = TmpClass
            TmpClass = AtomicSimpleCPU
        else:
            test_mem_mode = 'timing'

    return (TmpClass, test_mem_mode, CPUClass)
...

Testing MyCPU

Once you've edited the configuration scripts, you can run a M5 simulation from the top level directory with this command line:

me@mymachine:~/m5$build/MIPS_SE/m5.debug configs/example/se.py --my_cpu --cmd=tests/test-progs/hello/bin/mips/linux/hello

NOTE: This binary path refers to the m5/tests directory.

Summary

So the above "tutorial" showed you how to build your own CPU model in M5. Now, it's up to you to customize the CPU Model as you like and do your experiments! Good luck!