dram_ctrl.cc (10247:0ad233f0a77d) | dram_ctrl.cc (10286:e95a0ab1d368) |
---|---|
1/* 2 * Copyright (c) 2010-2014 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 53 unchanged lines hidden (view full) --- 62 prechargeEvent(this), refreshEvent(this), powerEvent(this), 63 drainManager(NULL), 64 deviceBusWidth(p->device_bus_width), burstLength(p->burst_length), 65 deviceRowBufferSize(p->device_rowbuffer_size), 66 devicesPerRank(p->devices_per_rank), 67 burstSize((devicesPerRank * burstLength * deviceBusWidth) / 8), 68 rowBufferSize(devicesPerRank * deviceRowBufferSize), 69 columnsPerRowBuffer(rowBufferSize / burstSize), | 1/* 2 * Copyright (c) 2010-2014 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 53 unchanged lines hidden (view full) --- 62 prechargeEvent(this), refreshEvent(this), powerEvent(this), 63 drainManager(NULL), 64 deviceBusWidth(p->device_bus_width), burstLength(p->burst_length), 65 deviceRowBufferSize(p->device_rowbuffer_size), 66 devicesPerRank(p->devices_per_rank), 67 burstSize((devicesPerRank * burstLength * deviceBusWidth) / 8), 68 rowBufferSize(devicesPerRank * deviceRowBufferSize), 69 columnsPerRowBuffer(rowBufferSize / burstSize), |
70 columnsPerStripe(range.granularity() / burstSize), |
|
70 ranksPerChannel(p->ranks_per_channel), 71 banksPerRank(p->banks_per_rank), channels(p->channels), rowsPerBank(0), 72 readBufferSize(p->read_buffer_size), 73 writeBufferSize(p->write_buffer_size), 74 writeHighThreshold(writeBufferSize * p->write_high_thresh_perc / 100.0), 75 writeLowThreshold(writeBufferSize * p->write_low_thresh_perc / 100.0), 76 minWritesPerSwitch(p->min_writes_per_switch), 77 writesThisTime(0), readsThisTime(0), --- 39 unchanged lines hidden (view full) --- 117 DPRINTF(DRAM, "Memory capacity %lld (%lld) bytes\n", capacity, 118 AbstractMemory::size()); 119 120 DPRINTF(DRAM, "Row buffer size %d bytes with %d columns per row buffer\n", 121 rowBufferSize, columnsPerRowBuffer); 122 123 rowsPerBank = capacity / (rowBufferSize * banksPerRank * ranksPerChannel); 124 | 71 ranksPerChannel(p->ranks_per_channel), 72 banksPerRank(p->banks_per_rank), channels(p->channels), rowsPerBank(0), 73 readBufferSize(p->read_buffer_size), 74 writeBufferSize(p->write_buffer_size), 75 writeHighThreshold(writeBufferSize * p->write_high_thresh_perc / 100.0), 76 writeLowThreshold(writeBufferSize * p->write_low_thresh_perc / 100.0), 77 minWritesPerSwitch(p->min_writes_per_switch), 78 writesThisTime(0), readsThisTime(0), --- 39 unchanged lines hidden (view full) --- 118 DPRINTF(DRAM, "Memory capacity %lld (%lld) bytes\n", capacity, 119 AbstractMemory::size()); 120 121 DPRINTF(DRAM, "Row buffer size %d bytes with %d columns per row buffer\n", 122 rowBufferSize, columnsPerRowBuffer); 123 124 rowsPerBank = capacity / (rowBufferSize * banksPerRank * ranksPerChannel); 125 |
126 // a bit of sanity checks on the interleaving |
|
125 if (range.interleaved()) { 126 if (channels != range.stripes()) 127 fatal("%s has %d interleaved address stripes but %d channel(s)\n", 128 name(), range.stripes(), channels); 129 130 if (addrMapping == Enums::RoRaBaChCo) { 131 if (rowBufferSize != range.granularity()) { | 127 if (range.interleaved()) { 128 if (channels != range.stripes()) 129 fatal("%s has %d interleaved address stripes but %d channel(s)\n", 130 name(), range.stripes(), channels); 131 132 if (addrMapping == Enums::RoRaBaChCo) { 133 if (rowBufferSize != range.granularity()) { |
132 fatal("Interleaving of %s doesn't match RoRaBaChCo " | 134 fatal("Channel interleaving of %s doesn't match RoRaBaChCo " |
133 "address map\n", name()); 134 } | 135 "address map\n", name()); 136 } |
135 } else if (addrMapping == Enums::RoRaBaCoCh) { 136 if (system()->cacheLineSize() != range.granularity()) { 137 fatal("Interleaving of %s doesn't match RoRaBaCoCh " 138 "address map\n", name()); | 137 } else if (addrMapping == Enums::RoRaBaCoCh || 138 addrMapping == Enums::RoCoRaBaCh) { 139 // for the interleavings with channel bits in the bottom, 140 // if the system uses a channel striping granularity that 141 // is larger than the DRAM burst size, then map the 142 // sequential accesses within a stripe to a number of 143 // columns in the DRAM, effectively placing some of the 144 // lower-order column bits as the least-significant bits 145 // of the address (above the ones denoting the burst size) 146 assert(columnsPerStripe >= 1); 147 148 // channel striping has to be done at a granularity that 149 // is equal or larger to a cache line 150 if (system()->cacheLineSize() > range.granularity()) { 151 fatal("Channel interleaving of %s must be at least as large " 152 "as the cache line size\n", name()); |
139 } | 153 } |
140 } else if (addrMapping == Enums::RoCoRaBaCh) { 141 if (system()->cacheLineSize() != range.granularity()) 142 fatal("Interleaving of %s doesn't match RoCoRaBaCh " 143 "address map\n", name()); | 154 155 // ...and equal or smaller than the row-buffer size 156 if (rowBufferSize < range.granularity()) { 157 fatal("Channel interleaving of %s must be at most as large " 158 "as the row-buffer size\n", name()); 159 } 160 // this is essentially the check above, so just to be sure 161 assert(columnsPerStripe <= columnsPerRowBuffer); |
144 } 145 } 146 147 // some basic sanity checks 148 if (tREFI <= tRP || tREFI <= tRFC) { 149 fatal("tREFI (%d) must be larger than tRP (%d) and tRFC (%d)\n", 150 tREFI, tRP, tRFC); 151 } --- 71 unchanged lines hidden (view full) --- 223 // Ro, Ra, Co, Ba and Ch denoting row, rank, column, bank and 224 // channel, respectively 225 uint8_t rank; 226 uint8_t bank; 227 // use a 64-bit unsigned during the computations as the row is 228 // always the top bits, and check before creating the DRAMPacket 229 uint64_t row; 230 | 162 } 163 } 164 165 // some basic sanity checks 166 if (tREFI <= tRP || tREFI <= tRFC) { 167 fatal("tREFI (%d) must be larger than tRP (%d) and tRFC (%d)\n", 168 tREFI, tRP, tRFC); 169 } --- 71 unchanged lines hidden (view full) --- 241 // Ro, Ra, Co, Ba and Ch denoting row, rank, column, bank and 242 // channel, respectively 243 uint8_t rank; 244 uint8_t bank; 245 // use a 64-bit unsigned during the computations as the row is 246 // always the top bits, and check before creating the DRAMPacket 247 uint64_t row; 248 |
231 // truncate the address to the access granularity | 249 // truncate the address to a DRAM burst, which makes it unique to 250 // a specific column, row, bank, rank and channel |
232 Addr addr = dramPktAddr / burstSize; 233 234 // we have removed the lowest order address bits that denote the 235 // position within the column 236 if (addrMapping == Enums::RoRaBaChCo) { 237 // the lowest order bits denote the column to ensure that 238 // sequential cache lines occupy the same row 239 addr = addr / columnsPerRowBuffer; --- 10 unchanged lines hidden (view full) --- 250 // over the ranks 251 rank = addr % ranksPerChannel; 252 addr = addr / ranksPerChannel; 253 254 // lastly, get the row bits 255 row = addr % rowsPerBank; 256 addr = addr / rowsPerBank; 257 } else if (addrMapping == Enums::RoRaBaCoCh) { | 251 Addr addr = dramPktAddr / burstSize; 252 253 // we have removed the lowest order address bits that denote the 254 // position within the column 255 if (addrMapping == Enums::RoRaBaChCo) { 256 // the lowest order bits denote the column to ensure that 257 // sequential cache lines occupy the same row 258 addr = addr / columnsPerRowBuffer; --- 10 unchanged lines hidden (view full) --- 269 // over the ranks 270 rank = addr % ranksPerChannel; 271 addr = addr / ranksPerChannel; 272 273 // lastly, get the row bits 274 row = addr % rowsPerBank; 275 addr = addr / rowsPerBank; 276 } else if (addrMapping == Enums::RoRaBaCoCh) { |
277 // take out the lower-order column bits 278 addr = addr / columnsPerStripe; 279 |
|
258 // take out the channel part of the address 259 addr = addr / channels; 260 | 280 // take out the channel part of the address 281 addr = addr / channels; 282 |
261 // next, the column 262 addr = addr / columnsPerRowBuffer; | 283 // next, the higher-order column bites 284 addr = addr / (columnsPerRowBuffer / columnsPerStripe); |
263 264 // after the column bits, we get the bank bits to interleave 265 // over the banks 266 bank = addr % banksPerRank; 267 addr = addr / banksPerRank; 268 269 // after the bank, we get the rank bits which thus interleaves 270 // over the ranks 271 rank = addr % ranksPerChannel; 272 addr = addr / ranksPerChannel; 273 274 // lastly, get the row bits 275 row = addr % rowsPerBank; 276 addr = addr / rowsPerBank; 277 } else if (addrMapping == Enums::RoCoRaBaCh) { 278 // optimise for closed page mode and utilise maximum 279 // parallelism of the DRAM (at the cost of power) 280 | 285 286 // after the column bits, we get the bank bits to interleave 287 // over the banks 288 bank = addr % banksPerRank; 289 addr = addr / banksPerRank; 290 291 // after the bank, we get the rank bits which thus interleaves 292 // over the ranks 293 rank = addr % ranksPerChannel; 294 addr = addr / ranksPerChannel; 295 296 // lastly, get the row bits 297 row = addr % rowsPerBank; 298 addr = addr / rowsPerBank; 299 } else if (addrMapping == Enums::RoCoRaBaCh) { 300 // optimise for closed page mode and utilise maximum 301 // parallelism of the DRAM (at the cost of power) 302 |
303 // take out the lower-order column bits 304 addr = addr / columnsPerStripe; 305 |
|
281 // take out the channel part of the address, not that this has 282 // to match with how accesses are interleaved between the 283 // controllers in the address mapping 284 addr = addr / channels; 285 286 // start with the bank bits, as this provides the maximum 287 // opportunity for parallelism between requests 288 bank = addr % banksPerRank; 289 addr = addr / banksPerRank; 290 291 // next get the rank bits 292 rank = addr % ranksPerChannel; 293 addr = addr / ranksPerChannel; 294 | 306 // take out the channel part of the address, not that this has 307 // to match with how accesses are interleaved between the 308 // controllers in the address mapping 309 addr = addr / channels; 310 311 // start with the bank bits, as this provides the maximum 312 // opportunity for parallelism between requests 313 bank = addr % banksPerRank; 314 addr = addr / banksPerRank; 315 316 // next get the rank bits 317 rank = addr % ranksPerChannel; 318 addr = addr / ranksPerChannel; 319 |
295 // next the column bits which we do not need to keep track of 296 // and simply skip past 297 addr = addr / columnsPerRowBuffer; | 320 // next, the higher-order column bites 321 addr = addr / (columnsPerRowBuffer / columnsPerStripe); |
298 299 // lastly, get the row bits 300 row = addr % rowsPerBank; 301 addr = addr / rowsPerBank; 302 } else 303 panic("Unknown address mapping policy chosen!"); 304 305 assert(rank < ranksPerChannel); --- 1531 unchanged lines hidden --- | 322 323 // lastly, get the row bits 324 row = addr % rowsPerBank; 325 addr = addr / rowsPerBank; 326 } else 327 panic("Unknown address mapping policy chosen!"); 328 329 assert(rank < ranksPerChannel); --- 1531 unchanged lines hidden --- |