mem: Add support for multi-channel DRAM configurations
authorAndreas Hansson <andreas.hansson@arm.com>
Fri, 1 Mar 2013 18:20:22 +0000 (13:20 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Fri, 1 Mar 2013 18:20:22 +0000 (13:20 -0500)
This patch adds support for multi-channel instances of the DRAM
controller model by stripping away the channel bits in the address
decoding. The patch relies on the availiability of address
interleaving and, at this time, it is up to the user to configure the
interleaving appropriately. At the moment it is assumed that the
channel interleaving bits are immediately following the column bits
(smallest sensible interleaving). Convenience methods for building
multi-channel configurations will be added later.

src/mem/SimpleDRAM.py
src/mem/simple_dram.cc
src/mem/simple_dram.hh

index 41bad93565ca4629f7253382abec7bc9007ac853..0e43a6a39a28829adb630612bf4f831118b3b0ab 100644 (file)
@@ -80,6 +80,10 @@ class SimpleDRAM(AbstractMemory):
     lines_per_rowbuffer = Param.Unsigned("Row buffer size in cache lines")
     ranks_per_channel = Param.Unsigned("Number of ranks per channel")
     banks_per_rank = Param.Unsigned("Number of banks per rank")
+    # only used for the address mapping as the controller by
+    # construction is a single channel and multiple controllers have
+    # to be instantiated for a multi-channel configuration
+    channels = Param.Unsigned(1, "Number of channels")
 
     # timing behaviour and constraints - all in nanoseconds
 
index d822fbeffbfdcce9efb65ff8f2eeeea55e2e92f3..ba5345c3fc64aa5f566eff2ff6654438cdde363e 100644 (file)
@@ -57,7 +57,7 @@ SimpleDRAM::SimpleDRAM(const SimpleDRAMParams* p) :
     bytesPerCacheLine(0),
     linesPerRowBuffer(p->lines_per_rowbuffer),
     ranksPerChannel(p->ranks_per_channel),
-    banksPerRank(p->banks_per_rank), rowsPerBank(0),
+    banksPerRank(p->banks_per_rank), channels(p->channels), rowsPerBank(0),
     readBufferSize(p->read_buffer_size),
     writeBufferSize(p->write_buffer_size),
     writeThresholdPerc(p->write_thresh_perc),
@@ -115,6 +115,23 @@ SimpleDRAM::init()
     rowsPerBank = capacity / (bytesPerCacheLine * linesPerRowBuffer *
                               banksPerRank * ranksPerChannel);
 
+    if (range.interleaved()) {
+        if (channels != range.stripes())
+            panic("%s has %d interleaved address stripes but %d channel(s)\n",
+                  name(), range.stripes(), channels);
+
+        if (addrMapping == Enums::openmap) {
+            if (bytesPerCacheLine * linesPerRowBuffer !=
+                range.granularity()) {
+                panic("Interleaving of %s doesn't match open address map\n",
+                      name());
+            }
+        } else if (addrMapping == Enums::closemap) {
+            if (bytesPerCacheLine != range.granularity())
+                panic("Interleaving of %s doesn't match closed address map\n",
+                      name());
+        }
+    }
 }
 
 void
@@ -190,6 +207,11 @@ SimpleDRAM::decodeAddr(PacketPtr pkt)
         // sequential cache lines occupy the same row
         addr = addr / linesPerRowBuffer;
 
+        // take out the channel part of the address, note that this has
+        // to match with how accesses are interleaved between the
+        // controllers in the address mapping
+        addr = addr / channels;
+
         // after the column bits, we get the bank bits to interleave
         // over the banks
         bank = addr % banksPerRank;
@@ -207,6 +229,11 @@ SimpleDRAM::decodeAddr(PacketPtr pkt)
         // optimise for closed page mode and utilise maximum
         // parallelism of the DRAM (at the cost of power)
 
+        // take out the channel part of the address, not that this has
+        // to match with how accesses are interleaved between the
+        // controllers in the address mapping
+        addr = addr / channels;
+
         // start with the bank bits, as this provides the maximum
         // opportunity for parallelism between requests
         bank = addr % banksPerRank;
index d8f51a7454e6c1248b1d93566e22c2455b8cf664..1f6e1a837cfce3e2610872c1602ee98441d09849 100644 (file)
@@ -378,6 +378,7 @@ class SimpleDRAM : public AbstractMemory
     const uint32_t linesPerRowBuffer;
     const uint32_t ranksPerChannel;
     const uint32_t banksPerRank;
+    const uint32_t channels;
     uint32_t rowsPerBank;
     const uint32_t readBufferSize;
     const uint32_t writeBufferSize;