From 66909dd5a2cf4cec0732eeeb389e3ff739fe58ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Wed, 22 Nov 2017 17:03:29 +0100 Subject: config, mem, hmc: fix HMC test script This patch keeps the logic behind the HMC model implementation untouched. Additional changes: - simple hello world script using HMC (SE simulation) Usage examples: ./build/ARM/gem5.opt configs/example/hmctest.py ./build/ARM/gem5.opt configs/example/hmctest.py --enable-global-monitor --enable-link-monitor --arch=same ./build/ARM/gem5.opt configs/example/hmctest.py --enable-global-monitor --enable-link-monitor --arch=mixed ./build/ARM/gem5.opt configs/example/hmc_hello.py ./build/ARM/gem5.opt configs/example/hmc_hello.py --enable-global-monitor --enable-link-monitor Change-Id: I64eb6c9abb45376b6ed72722926acddd50765394 Reviewed-on: https://gem5-review.googlesource.com/6061 Reviewed-by: Jason Lowe-Power Reviewed-by: Nikos Nikoleris Maintainer: Jason Lowe-Power --- configs/example/hmc_hello.py | 83 +++++++++++++++ configs/example/hmc_tgen.cfg | 36 +++++++ configs/example/hmctest.py | 248 +++++++++++++++++-------------------------- 3 files changed, 214 insertions(+), 153 deletions(-) create mode 100644 configs/example/hmc_hello.py create mode 100644 configs/example/hmc_tgen.cfg (limited to 'configs/example') diff --git a/configs/example/hmc_hello.py b/configs/example/hmc_hello.py new file mode 100644 index 000000000..d9a6c0f9e --- /dev/null +++ b/configs/example/hmc_hello.py @@ -0,0 +1,83 @@ +# Copyright (c) 2017, University of Kaiserslautern +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# 3. Neither the name of the copyright holder 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 HOLDER +# 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. +# +# Author: Éder F. Zulian + +import sys +import argparse + +import m5 +from m5.objects import * +from m5.util import * +addToPath('../') +from common import MemConfig +from common import HMC + + +pd = "Simple 'hello world' example using HMC as main memory" +parser = argparse.ArgumentParser(description=pd) +HMC.add_options(parser) +options = parser.parse_args() +# create the system we are going to simulate +system = System() +# use timing mode for the interaction between master-slave ports +system.mem_mode = 'timing' +# set the clock fequency of the system +clk = '1GHz' +vd = VoltageDomain(voltage='1V') +system.clk_domain = SrcClockDomain(clock=clk, voltage_domain=vd) +# create a simple CPU +system.cpu = TimingSimpleCPU() +# config memory system +MemConfig.config_mem(options, system) +# hook the CPU ports up to the membus +system.cpu.icache_port = system.membus.slave +system.cpu.dcache_port = system.membus.slave +# create the interrupt controller for the CPU and connect to the membus +system.cpu.createInterruptController() +# connect special port in the system to the membus. This port is a +# functional-only port to allow the system to read and write memory. +system.system_port = system.membus.slave +# get ISA for the binary to run. +isa = str(m5.defines.buildEnv['TARGET_ISA']).lower() +# run 'hello' and use the compiled ISA to find the binary +binary = 'tests/test-progs/hello/bin/' + isa + '/linux/hello' +# create a process for a simple "Hello World" application +process = Process() +# cmd is a list which begins with the executable (like argv) +process.cmd = [binary] +# set the cpu workload +system.cpu.workload = process +# create thread contexts +system.cpu.createThreads() +# set up the root SimObject +root = Root(full_system=False, system=system) +m5.instantiate() +m5.simulate() diff --git a/configs/example/hmc_tgen.cfg b/configs/example/hmc_tgen.cfg new file mode 100644 index 000000000..1dc0ffe10 --- /dev/null +++ b/configs/example/hmc_tgen.cfg @@ -0,0 +1,36 @@ +# This format supports comments using the '#' symbol as the leading +# character of the line +# +# The file format contains [STATE]+ [INIT] [TRANSITION]+ in any order, +# where the states are the nodes in the graph, init describes what +# state to start in, and transition describes the edges of the graph. +# +# STATE +# +# State IDLE idles +# +# States LINEAR and RANDOM have additional: +# STATE = [LINEAR, RANDOM] +# +# +# +# +# +# +# +# +# +# +# +# State TRACE plays back a pre-recorded trace once +# +# Addresses are expressed as decimal numbers, both in the +# configuration and the trace file. The period in the linear and +# random state is from a uniform random distribution over the +# interval. If a specific value is desired, then the min and max can +# be set to the same value. +STATE 0 100 IDLE +STATE 1 10000000 LINEAR 100 2147483648 2181038080 64 30000 30000 0 +INIT 0 +TRANSITION 0 1 1 +TRANSITION 1 0 1 diff --git a/configs/example/hmctest.py b/configs/example/hmctest.py index 3e0fa124a..9ed3ef45d 100644 --- a/configs/example/hmctest.py +++ b/configs/example/hmctest.py @@ -1,171 +1,113 @@ -import optparse import sys +import argparse import subprocess +from pprint import pprint import m5 from m5.objects import * -from m5.util import addToPath +from m5.util import * addToPath('../') from common import MemConfig from common import HMC -parser = optparse.OptionParser() -# Use a HMC_2500_1x32 (1 channel, 32-bits wide) by default -parser.add_option("--mem-type", type = "choice", default = "HMC_2500_1x32", - choices = MemConfig.mem_names(), - help = "type of memory to use") - -parser.add_option("--ranks", "-r", type = "int", default = 1, - help = "Number of ranks to iterate across") - -parser.add_option("--rd_perc", type ="int", default=100, - help = "Percentage of read commands") - -parser.add_option("--mode", type ="choice", default ="DRAM", - choices = ["DRAM", "DRAM_ROTATE", "RANDOM"], - help = "DRAM: Random traffic; \ - DRAM_ROTATE: Traffic rotating across banks and ranks" - ) - -parser.add_option("--addr_map", type ="int", default = 1, - help = "0: RoCoRaBaCh; 1: RoRaBaCoCh/RoRaBaChCo") - -parser.add_option("--arch", type = "choice", default = "distributed", - choices = ["same", "distributed", "mixed"], - help = "same: HMC-4 links with same range\ - distributed: HMC-4 links with distributed range\ - mixed: mixed with same & distributed range") - -parser.add_option("--linkaggr", type = "int", default = 0, - help = "1: enable link crossbar, 0: disable link crossbar") - -parser.add_option("--num_cross", type = "int", default = 4, - help = "1: number of crossbar in HMC=1;\ - 4: number of crossbar = 4") - -parser.add_option("--tlm-memory", type = "string", - help="use external port for SystemC TLM cosimulation") - -parser.add_option("--elastic-trace-en", action ="store_true", - help = """Enable capture of data dependency and instruction - fetch traces using elastic trace probe.""") - -(options, args) = parser.parse_args() - -if args: - print "Error: script doesn't take any positional arguments" - sys.exit(1) - -system = System() -system.clk_domain = SrcClockDomain(clock='100GHz', - voltage_domain= - VoltageDomain(voltage = '1V')) -# Create additional crossbar for arch1 -if options.arch == "distributed" or options.arch == "mixed" : - system.membus = NoncoherentXBar( width=8 ) - system.membus.badaddr_responder = BadAddr() - system.membus.default = Self.badaddr_responder.pio - system.membus.width = 8 - system.membus.frontend_latency = 3 - system.membus.forward_latency = 4 - system.membus.response_latency = 2 - - system.membus.clk_domain = SrcClockDomain(clock='100GHz', voltage_domain= - VoltageDomain(voltage = '1V')) - -# we are considering 4GB HMC device with following parameters +def add_options(parser): + parser.add_argument("--external-memory-system", default=0, action="store", + type=int, help="External memory system") + # TLM related options, currently optional in configs/common/MemConfig.py + parser.add_argument("--tlm-memory", action="store_true", help="use\ + external port for SystemC TLM co-simulation. Default:\ + no") + # Elastic traces related options, currently optional in + # configs/common/MemConfig.py + parser.add_argument("--elastic-trace-en", action="store_true", + help="enable capture of data dependency and\ + instruction fetch traces using elastic trace\ + probe.\nDefault: no") + # Options related to traffic generation + parser.add_argument("--num-tgen", default=4, action="store", type=int, + choices=[4], help="number of traffic generators.\ + Right now this script supports only 4.\nDefault: 4") + parser.add_argument("--tgen-cfg-file", + default="./configs/example/hmc_tgen.cfg", + type=str, help="Traffic generator(s) configuration\ + file. Note: this script uses the same configuration\ + file for all traffic generators") + + +# considering 4GB HMC device with following parameters # hmc_device_size = '4GB' -# hmc_num_vaults = 16 # hmc_vault_size = '256MB' # hmc_stack_size = 8 # hmc_bank_in_stack = 2 # hmc_bank_size = '16MB' # hmc_bank_in_vault = 16 - -# determine the burst length in bytes -burst_size = 256 -num_serial_links = 4 -num_vault_ctrl = 16 -options.mem_channels = 1 -options.external_memory_system = 0 -options.mem_ranks=1 -stride_size = burst_size -system.cache_line_size = burst_size - -# Enable performance monitoring -options.enable_global_monitor = True -options.enable_link_monitor = False - -# Bytes used for calculations -oneGBytes = 1024 * 1024 * 1024 -oneMBytes = 1024 * 1024 - -# Memory ranges of 16 vault controller - Total_HMC_size / 16 -mem_range_vault = [ AddrRange(i * 256 * oneMBytes, ((i + 1) * 256 * oneMBytes) - - 1) - for i in range(num_vault_ctrl)] - -# Memmory ranges of serial link for arch-0 -# Same as the ranges of vault controllers - 4 vault - to - 1 serial link -if options.arch == "same": - ser_range = [ AddrRange(0, (4 * oneGBytes) - 1) - for i in range(num_serial_links)] - options.ser_ranges = ser_range - -# Memmory ranges of serial link for arch-1 -# Distributed range accross links -if options.arch == "distributed": - ser_range = [ AddrRange(i * oneGBytes, ((i + 1) * oneGBytes) - 1) - for i in range(num_serial_links)] - options.ser_ranges = ser_range - -# Memmory ranges of serial link for arch-2 -# "Mixed" address distribution over links -if options.arch == "mixed": - ser_range0 = AddrRange(0 , (1 * oneGBytes) - 1) - ser_range1 = AddrRange(1 * oneGBytes , (2 * oneGBytes) - 1) - ser_range2 = AddrRange(0 , (4 * oneGBytes) - 1) - ser_range3 = AddrRange(0 , (4 * oneGBytes) - 1) - options.ser_ranges = [ser_range0, ser_range1, ser_range2, ser_range3] - -# Assign ranges of vault controller to system ranges -system.mem_ranges = mem_range_vault - -# open traffic generator -cfg_file_name = "./tests/quick/se/70.tgen/traffic.cfg" -cfg_file = open(cfg_file_name, 'r') - -# number of traffic generator -np = 4 -# create a traffic generator, and point it to the file we just created -system.tgen = [ TrafficGen(config_file = cfg_file_name) for i in xrange(np)] - -# Config memory system with given HMC arch -MemConfig.config_mem(options, system) - -if options.arch == "distributed": - for i in xrange(np): - system.tgen[i].port = system.membus.slave - # connect the system port even if it is not used in this example - system.system_port = system.membus.slave - -if options.arch == "mixed": - for i in xrange(int(np/2)): - system.tgen[i].port = system.membus.slave - # connect the system port even if it is not used in this example - system.system_port = system.membus.slave - - -# run Forrest, run! -root = Root(full_system = False, system = system) -root.system.mem_mode = 'timing' - -m5.instantiate() -m5.simulate(10000000000) - -m5.stats.dump() - -print "Done!" +def build_system(options): + # create the system we are going to simulate + system = System() + # use timing mode for the interaction between master-slave ports + system.mem_mode = 'timing' + # set the clock fequency of the system + clk = '100GHz' + vd = VoltageDomain(voltage='1V') + system.clk_domain = SrcClockDomain(clock=clk, voltage_domain=vd) + # add traffic generators to the system + system.tgen = [TrafficGen(config_file=options.tgen_cfg_file) for i in + xrange(options.num_tgen)] + # Config memory system with given HMC arch + MemConfig.config_mem(options, system) + # Connect the traffic generatiors + if options.arch == "distributed": + for i in xrange(options.num_tgen): + system.tgen[i].port = system.membus.slave + # connect the system port even if it is not used in this example + system.system_port = system.membus.slave + if options.arch == "mixed": + for i in xrange(int(options.num_tgen/2)): + system.tgen[i].port = system.membus.slave + hh = system.hmc_host + if options.enable_global_monitor: + system.tgen[2].port = hh.lmonitor[2].slave + hh.lmonitor[2].master = hh.seriallink[2].slave + system.tgen[3].port = hh.lmonitor[3].slave + hh.lmonitor[3].master = hh.seriallink[3].slave + else: + system.tgen[2].port = hh.seriallink[2].slave + system.tgen[3].port = hh.seriallink[3].slave + # connect the system port even if it is not used in this example + system.system_port = system.membus.slave + if options.arch == "same": + hh = system.hmc_host + for i in xrange(options.num_links_controllers): + if options.enable_global_monitor: + system.tgen[i].port = hh.lmonitor[i].slave + else: + system.tgen[i].port = hh.seriallink[i].slave + # set up the root SimObject + root = Root(full_system=False, system=system) + return root + + +def main(): + parser = argparse.ArgumentParser(description="Simple system using HMC as\ + main memory") + HMC.add_options(parser) + add_options(parser) + options = parser.parse_args() + # build the system + root = build_system(options) + # instantiate all of the objects we've created so far + m5.instantiate() + print "Beginning simulation!" + event = m5.simulate(10000000000) + m5.stats.dump() + print 'Exiting @ tick %i because %s (exit code is %i)' % (m5.curTick(), + event.getCause(), + event.getCode()) + print "Done" + + +if __name__ == "__m5_main__": + main() -- cgit v1.2.3