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
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)")
from Benchmarks import *
import Simulation
import CacheConfig
+import MemConfig
from Caches import *
import Options
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':
import Ruby
import Simulation
import CacheConfig
+import MemConfig
from Caches import *
from cpu2000 import *
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
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)
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)
type = 'SimpleDRAM'
cxx_header = "mem/simple_dram.hh"
- @classmethod
- def makeMultiChannel(cls, nbr_mem_ctrls, mem_start_addr, mem_size,
- intlv_high_bit = 11):
- """
- Make a multi-channel configuration of this class.
-
- Create multiple instances of the specific class and set their
- parameters such that the address range is interleaved between
- them.
-
- Returns a list of controllers.
- """
- 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")
- mem_ctrls = []
- for i in xrange(nbr_mem_ctrls):
- # The default interleaving granularity is tuned to match a
- # row buffer size of 32 cache lines of 64 bytes (starting
- # at bit 11 for 2048 bytes). There is unfortunately no
- # good way of checking this at instantiation time.
- mem_ctrls.append(cls(range = AddrRange(mem_start_addr,
- size = mem_size,
- intlvHighBit = \
- intlv_high_bit,
- intlvBits = intlv_bits,
- intlvMatch = i),
- channels = nbr_mem_ctrls))
- return mem_ctrls
-
# single-ported on the system interface side, instantiate with a
# bus in front of the controller for multiple ports
port = SlavePort("Slave port")