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;