Files
gem5/configs/example/arm/etrace_se.py
Erin Le e1db67c4bd configs, dev, learning-gem5, python, tests: more clarification
This commit contains the rest of the base 2 vs base 10 cache/memory
size clarifications. It also changes the warning message to use
warn(). With these changes, the warning message should now no
longer show up during a fresh compilation of gem5.

Change-Id: Ia63f841bdf045b76473437f41548fab27dc19631
2024-08-23 18:02:42 -07:00

192 lines
6.6 KiB
Python

# Copyright (c) 2016-2017, 2022-2023 Arm Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder. You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# 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.
import argparse
import os
import shlex
import m5
from m5.objects import *
from m5.util import addToPath
m5.util.addToPath("../..")
import devices
from common import ObjectList
def get_processes(cmd):
"""Interprets commands to run and returns a list of processes"""
cwd = os.getcwd()
multiprocesses = []
for idx, c in enumerate(cmd):
argv = shlex.split(c)
process = Process(pid=100 + idx, cwd=cwd, cmd=argv, executable=argv[0])
process.gid = os.getgid()
print("info: %d. command and arguments: %s" % (idx + 1, process.cmd))
multiprocesses.append(process)
return multiprocesses
def create(args):
"""Create and configure the system object."""
system = devices.SimpleSeSystem(
mem_mode="timing",
)
# Add CPUs to the system. A cluster of CPUs typically have
# private L1 caches and a shared L2 cache.
system.cpu_cluster = devices.ArmCpuCluster(
system,
args.num_cores,
args.cpu_freq,
"1.2V",
ObjectList.cpu_list.get("O3_ARM_v7a_3_Etrace"),
devices.L1I,
devices.L1D,
devices.L2,
)
# Attach the elastic trace probe listener to every CPU in the cluster
for cpu in system.cpu_cluster:
cpu.attach_probe_listener(args.inst_trace_file, args.data_trace_file)
# As elastic trace generation is enabled, make sure the memory system is
# minimal so that compute delays do not include memory access latencies.
# Configure the compulsory L1 caches for the O3CPU, do not configure
# any more caches.
system.addCaches(True, last_cache_level=1)
# For elastic trace, over-riding Simple Memory latency to 1ns."
system.memory = SimpleMemory(
range=AddrRange(start=0, size=args.mem_size),
latency="1ns",
port=system.membus.mem_side_ports,
)
# Parse the command line and get a list of Processes instances
# that we can pass to gem5.
processes = get_processes(args.commands_to_run)
if len(processes) != args.num_cores:
print(
"Error: Cannot map %d command(s) onto %d CPU(s)"
% (len(processes), args.num_cores)
)
sys.exit(1)
system.workload = SEWorkload.init_compatible(processes[0].executable)
# Assign one workload to each CPU
for cpu, workload in zip(system.cpu_cluster.cpus, processes):
cpu.workload = workload
return system
def main():
parser = argparse.ArgumentParser(epilog=__doc__)
parser.add_argument(
"commands_to_run",
metavar="command(s)",
nargs="+",
help="Command(s) to run",
)
parser.add_argument(
"--inst-trace-file",
action="store",
type=str,
help="""Instruction fetch trace file input to
Elastic Trace probe in a capture simulation and
Trace CPU in a replay simulation""",
default="fetchtrace.proto.gz",
)
parser.add_argument(
"--data-trace-file",
action="store",
type=str,
help="""Data dependency trace file input to
Elastic Trace probe in a capture simulation and
Trace CPU in a replay simulation""",
default="deptrace.proto.gz",
)
parser.add_argument("--cpu-freq", type=str, default="4GHz")
parser.add_argument(
"--num-cores", type=int, default=1, help="Number of CPU cores"
)
parser.add_argument(
"--mem-size",
action="store",
type=str,
default="2GiB",
help="Specify the physical memory size",
)
args = parser.parse_args()
# Create a single root node for gem5's object hierarchy. There can
# only exist one root node in the simulator at any given
# time. Tell gem5 that we want to use syscall emulation mode
# instead of full system mode.
root = Root(full_system=False)
# Populate the root node with a system. A system corresponds to a
# single node with shared memory.
root.system = create(args)
# Instantiate the C++ object hierarchy. After this point,
# SimObjects can't be instantiated anymore.
m5.instantiate()
# Start the simulator. This gives control to the C++ world and
# starts the simulator. The returned event tells the simulation
# script why the simulator exited.
event = m5.simulate()
# Print the reason for the simulation exit. Some exit codes are
# requests for service (e.g., checkpoints) from the simulation
# script. We'll just ignore them here and exit.
print(f"{event.getCause()} ({event.getCode()}) @ {m5.curTick()}")
if __name__ == "__m5_main__":
main()