mem: Add a method to build multi-channel DRAM configurations
authorAndreas Hansson <andreas.hansson@arm.com>
Fri, 1 Mar 2013 18:20:32 +0000 (13:20 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Fri, 1 Mar 2013 18:20:32 +0000 (13:20 -0500)
This patch adds a class method that allows easy creation of
channel-interleaved multi-channel DRAM configurations. It is enabled
by a class method to allow customisation of the class independent of
the channel configuration. For example, the user can create a MyDDR
subclass of e.g. SimpleDDR3, and then create a four-channel
configuration of the subclass by calling MyDDR.makeMultiChannel(4,
mem_start, mem_size).

src/mem/SimpleDRAM.py

index 0e43a6a39a28829adb630612bf4f831118b3b0ab..60bc1cffb5ea9bd8e7277d3b69985c044e7383c4 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 ARM Limited
+# Copyright (c) 2012-2013 ARM Limited
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
@@ -59,6 +59,38 @@ class SimpleDRAM(AbstractMemory):
     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")