summaryrefslogtreecommitdiff
path: root/configs
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2013-08-19 03:52:34 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2013-08-19 03:52:34 -0400
commitc26911013c799d63dfe854de8cce11137324cde2 (patch)
tree78146c1582a62407565da5b2bac34581b021015f /configs
parent49d88f08b0ff463bca04285dca240b3730889a1d (diff)
downloadgem5-c26911013c799d63dfe854de8cce11137324cde2.tar.xz
config: Command line support for multi-channel memory
This patch adds support for specifying multi-channel memory configurations on the command line, e.g. 'se/fs.py --mem-type=ddr3_1600_x64 --mem-channels=4'. To enable this, it enhances the functionality of MemConfig and moves the existing makeMultiChannel class method from SimpleDRAM to the support scripts. The se/fs.py example scripts are updated to make use of the new feature.
Diffstat (limited to 'configs')
-rw-r--r--configs/common/MemConfig.py67
-rw-r--r--configs/common/Options.py2
-rw-r--r--configs/example/fs.py8
-rw-r--r--configs/example/se.py8
4 files changed, 76 insertions, 9 deletions
diff --git a/configs/common/MemConfig.py b/configs/common/MemConfig.py
index 6630be8ec..a74ff1d62 100644
--- a/configs/common/MemConfig.py
+++ b/configs/common/MemConfig.py
@@ -124,3 +124,70 @@ for alias, target in _mem_aliases_all:
elif target in _mem_classes:
# Normal alias
_mem_aliases[alias] = target
+
+def config_mem(options, system):
+ """
+ Create the memory controllers based on the options and attach them.
+
+ If requested, we make a multi-channel configuration of the
+ selected memory controller class by creating multiple instances of
+ the specific class. The individual controllers have their
+ parameters set such that the address range is interleaved between
+ them.
+ """
+
+ nbr_mem_ctrls = options.mem_channels
+ import math
+ from m5.util import fatal
+ intlv_bits = int(math.log(nbr_mem_ctrls, 2))
+ if 2 ** intlv_bits != nbr_mem_ctrls:
+ fatal("Number of memory channels must be a power of 2")
+ cls = get(options.mem_type)
+ mem_ctrls = []
+
+ # The default behaviour is to interleave on cache line granularity
+ cache_line_bit = int(math.log(system.cache_line_size.value, 2)) - 1
+ intlv_low_bit = cache_line_bit
+
+ # For every range (most systems will only have one), create an
+ # array of controllers and set their parameters to match their
+ # address mapping in the case of a DRAM
+ for r in system.mem_ranges:
+ for i in xrange(nbr_mem_ctrls):
+ # Create an instance so we can figure out the address
+ # mapping and row-buffer size
+ ctrl = cls()
+
+ # Only do this for DRAMs
+ if issubclass(cls, m5.objects.SimpleDRAM):
+ # Inform each controller how many channels to account
+ # for
+ ctrl.channels = nbr_mem_ctrls
+
+ # If the channel bits are appearing after the column
+ # bits, we need to add the appropriate number of bits
+ # for the row buffer size
+ if ctrl.addr_mapping.value == 'RaBaChCo':
+ # This computation only really needs to happen
+ # once, but as we rely on having an instance we
+ # end up having to repeat it for each and every
+ # one
+ rowbuffer_size = ctrl.device_rowbuffer_size.value * \
+ ctrl.devices_per_rank.value
+
+ intlv_low_bit = int(math.log(rowbuffer_size, 2)) - 1
+
+ # We got all we need to configure the appropriate address
+ # range
+ ctrl.range = m5.objects.AddrRange(r.start, size = r.size(),
+ intlvHighBit = \
+ intlv_low_bit + intlv_bits,
+ intlvBits = intlv_bits,
+ intlvMatch = i)
+ mem_ctrls.append(ctrl)
+
+ system.mem_ctrls = mem_ctrls
+
+ # Connect the controllers to the membus
+ for i in xrange(nbr_mem_ctrls):
+ system.mem_ctrls[i].port = system.membus.master
diff --git a/configs/common/Options.py b/configs/common/Options.py
index 73def510c..6431d460f 100644
--- a/configs/common/Options.py
+++ b/configs/common/Options.py
@@ -88,6 +88,8 @@ def addCommonOptions(parser):
parser.add_option("--mem-type", type="choice", default="simple_mem",
choices=MemConfig.mem_names(),
help = "type of memory to use")
+ parser.add_option("--mem-channels", type="int", default=1,
+ help = "number of memory channels")
parser.add_option("--mem-size", action="store", type="string",
default="512MB",
help="Specify the physical memory size (single memory)")
diff --git a/configs/example/fs.py b/configs/example/fs.py
index bcd58ca5e..4d6d87eb8 100644
--- a/configs/example/fs.py
+++ b/configs/example/fs.py
@@ -53,6 +53,7 @@ from SysPaths import *
from Benchmarks import *
import Simulation
import CacheConfig
+import MemConfig
from Caches import *
import Options
@@ -171,12 +172,7 @@ for i in xrange(np):
test_sys.cpu[i].createThreads()
CacheConfig.config_cache(options, test_sys)
-
-# Create the appropriate memory controllers and connect them to the
-# memory bus
-test_sys.mem_ctrls = [TestMemClass(range = r) for r in test_sys.mem_ranges]
-for i in xrange(len(test_sys.mem_ctrls)):
- test_sys.mem_ctrls[i].port = test_sys.membus.master
+MemConfig.config_mem(options, test_sys)
if len(bm) == 2:
if buildEnv['TARGET_ISA'] == 'alpha':
diff --git a/configs/example/se.py b/configs/example/se.py
index 39572cd86..02a0d3b96 100644
--- a/configs/example/se.py
+++ b/configs/example/se.py
@@ -58,6 +58,7 @@ import Options
import Ruby
import Simulation
import CacheConfig
+import MemConfig
from Caches import *
from cpu2000 import *
@@ -157,8 +158,8 @@ if options.smt and options.num_cpus > 1:
np = options.num_cpus
system = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)],
- physmem = MemClass(range=AddrRange(options.mem_size)),
mem_mode = test_mem_mode,
+ mem_ranges = [AddrRange(options.mem_size)],
cache_line_size = options.cacheline_size)
# Create a top-level voltage domain
@@ -221,7 +222,8 @@ if options.ruby:
sys.exit(1)
# Set the option for physmem so that it is not allocated any space
- system.physmem.null = True
+ system.physmem = MemClass(range=AddrRange(options.mem_size),
+ null = True)
options.use_map = True
Ruby.create_system(options, system)
@@ -247,8 +249,8 @@ if options.ruby:
else:
system.membus = CoherentBus()
system.system_port = system.membus.slave
- system.physmem.port = system.membus.master
CacheConfig.config_cache(options, system)
+ MemConfig.config_mem(options, system)
root = Root(full_system = False, system = system)
Simulation.run(options, root, system, FutureClass)