summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/SimpleDRAM.py4
-rw-r--r--src/mem/simple_dram.cc29
-rw-r--r--src/mem/simple_dram.hh1
3 files changed, 33 insertions, 1 deletions
diff --git a/src/mem/SimpleDRAM.py b/src/mem/SimpleDRAM.py
index 41bad9356..0e43a6a39 100644
--- a/src/mem/SimpleDRAM.py
+++ b/src/mem/SimpleDRAM.py
@@ -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
diff --git a/src/mem/simple_dram.cc b/src/mem/simple_dram.cc
index d822fbeff..ba5345c3f 100644
--- a/src/mem/simple_dram.cc
+++ b/src/mem/simple_dram.cc
@@ -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;
diff --git a/src/mem/simple_dram.hh b/src/mem/simple_dram.hh
index d8f51a745..1f6e1a837 100644
--- a/src/mem/simple_dram.hh
+++ b/src/mem/simple_dram.hh
@@ -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;