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 ---