Skip to main content

The System Object

Congrats, now we can start writing real gem5 script stuff. Our first such line of code is

system = System()

Congrats, you just built a computer, go tell your mom (no really, you probably haven't called your mom in a bit, go do that now and come back in 5 minutes).

Why did I do that?

The system object is the most important part, you can find the source code detailing all the options for the system in $GEM_SRC/sim/system.py. Think of this like your motherboard. On it, you will place your processor(s), your memory and any other system objects. You can then feed this system a workload (possibly multithreaded), and then observe the results through the statistics you collect, more about that later.

Adding Components

Now that we have a system, we can begin adding components. Consider first a clock domain:

system.clk_domain = SrcClockDomain()
system.clk_domain.clock = '1GHz'
system.clk_domain.voltage_domain = VoltageDomain()

Now that we have a reference clock for timing, we can enable timing mode for the memory system:

system.mem_mode = 'timing'
system.mem_ranges = [AddrRange('512MB')]

So now that we have a bit of memory, we can attach a processor:

system.cpu = RiscvTimingSimpleCPU()
SimObjects

The gem5 ecosystem revolves around the idea of SimObjects being simple m5 objects that we construct using python and C++ that can then be added to the system directly. They are also the reason I cannot provide a full listing of fields or methods for any classes in gem5, there are a lot of layers to this here program.

Layers

Connecting Memory

Now that we have all the components necessary to run a program, we can connect them all together. This is done through a system memory bus. A processor will also require an interrupt controller, which we will also attach here.

# System membus
system.membus = SystemXBar() # our crossbar

# Cache ports!
system.cpu.icache_port = system.membus.cpu_side_ports
system.cpu.dcache_port = system.membus.cpu_side_ports

# Setup an interrupt controller
system.cpu.createInterruptController()
system.system_port = system.membus.cpu_side_ports

Memory Control

Before we finally get to running a process with our fancy little processor, we need to add in some memory control to make sure that everything functions as expected.

# MEMORYYYYY
system.mem_ctrl = MemCtrl()
system.mem_ctrl.dram = DDR3_1600_8x8()
system.mem_ctrl.dram.range = system.mem_ranges[0]
system.mem_ctrl.port = system.membus.mem_side_ports

The Code so Far

#### IMPORTS ####
# import the m5 (gem5) library created when gem5 is built
import m5
import os
import sys

# import all of the SimObjects
from m5.objects import *
from m5.util import fatal

#### CONSTANTS ####
try:
os.environ['GEM_TESTS']
os.environ['GEM_PATH']
os.environ['GEM_CONFIGS']
except e:
fatal("This script requires the GEM_TESTS, GEM_PATH and GEM_CONFIGS environment variables")

# Add the common scripts to our path
# m5.util.addToPath(os.environ['GEM_CONFIGS'])
sys.path.append(os.environ['GEM_CONFIGS'])

# Creaing a simple system
system = System() # YAAAAAAAAAAAY

# We can now reference the system and change some parameters
system.clk_domain = SrcClockDomain()
system.clk_domain.clock = '1GHz'
system.clk_domain.voltage_domain = VoltageDomain()

# now we set the memory
system.mem_mode = 'timing'
system.mem_ranges = [AddrRange('512MB')]

# The type of CPU
system.cpu = RiscvTimingSimpleCPU()

# System membus
system.membus = SystemXBar()

# Cache ports!
system.cpu.icache_port = system.membus.cpu_side_ports
system.cpu.dcache_port = system.membus.cpu_side_ports

# Setup an interrupt controller
system.cpu.createInterruptController()
system.system_port = system.membus.cpu_side_ports
# NOTE: RISCV does not require the PIO setup they have in the tutorial

# MEMORYYYYY
system.mem_ctrl = MemCtrl()
system.mem_ctrl.dram = DDR3_1600_8x8()
system.mem_ctrl.dram.range = system.mem_ranges[0]
system.mem_ctrl.port = system.membus.mem_side_ports

This tutorial is heavily based on learning gem5 with some modifications for the University of Alberta CMPUT 429 course made by Ayrton Chilibeck in Summer 2024.