summaryrefslogtreecommitdiff
path: root/configs/common/MemConfig.py
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/common/MemConfig.py
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/common/MemConfig.py')
-rw-r--r--configs/common/MemConfig.py67
1 files changed, 67 insertions, 0 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