changeset 4411b4e0c03a in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=4411b4e0c03a
description:
        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:

 configs/common/MemConfig.py |  67 +++++++++++++++++++++++++++++++++++++++++++++
 configs/common/Options.py   |   2 +
 configs/example/fs.py       |   8 +----
 configs/example/se.py       |   8 +++--
 src/mem/SimpleDRAM.py       |  32 ---------------------
 5 files changed, 76 insertions(+), 41 deletions(-)

diffs (194 lines):

diff -r cc7a7fc71c42 -r 4411b4e0c03a configs/common/MemConfig.py
--- a/configs/common/MemConfig.py       Mon Aug 19 03:52:33 2013 -0400
+++ b/configs/common/MemConfig.py       Mon Aug 19 03:52:34 2013 -0400
@@ -124,3 +124,70 @@
     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 -r cc7a7fc71c42 -r 4411b4e0c03a configs/common/Options.py
--- a/configs/common/Options.py Mon Aug 19 03:52:33 2013 -0400
+++ b/configs/common/Options.py Mon Aug 19 03:52:34 2013 -0400
@@ -88,6 +88,8 @@
     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 -r cc7a7fc71c42 -r 4411b4e0c03a configs/example/fs.py
--- a/configs/example/fs.py     Mon Aug 19 03:52:33 2013 -0400
+++ b/configs/example/fs.py     Mon Aug 19 03:52:34 2013 -0400
@@ -53,6 +53,7 @@
 from Benchmarks import *
 import Simulation
 import CacheConfig
+import MemConfig
 from Caches import *
 import Options
 
@@ -171,12 +172,7 @@
     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 -r cc7a7fc71c42 -r 4411b4e0c03a configs/example/se.py
--- a/configs/example/se.py     Mon Aug 19 03:52:33 2013 -0400
+++ b/configs/example/se.py     Mon Aug 19 03:52:34 2013 -0400
@@ -58,6 +58,7 @@
 import Ruby
 import Simulation
 import CacheConfig
+import MemConfig
 from Caches import *
 from cpu2000 import *
 
@@ -157,8 +158,8 @@
 
 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 @@
         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 @@
 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)
diff -r cc7a7fc71c42 -r 4411b4e0c03a src/mem/SimpleDRAM.py
--- a/src/mem/SimpleDRAM.py     Mon Aug 19 03:52:33 2013 -0400
+++ b/src/mem/SimpleDRAM.py     Mon Aug 19 03:52:34 2013 -0400
@@ -64,38 +64,6 @@
     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")
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to