dram_ctrl.cc (10883:9294c4a60251) dram_ctrl.cc (10889:c4c13fced000)
1/*
1/*
2 * Copyright (c) 2010-2014 ARM Limited
2 * Copyright (c) 2010-2015 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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated

--- 81 unchanged lines hidden (view full) ---

92 busBusyUntil(0), prevArrival(0),
93 nextReqTime(0), activeRank(0), timeStampOffset(0)
94{
95 // sanity check the ranks since we rely on bit slicing for the
96 // address decoding
97 fatal_if(!isPowerOf2(ranksPerChannel), "DRAM rank count of %d is not "
98 "allowed, must be a power of two\n", ranksPerChannel);
99
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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated

--- 81 unchanged lines hidden (view full) ---

92 busBusyUntil(0), prevArrival(0),
93 nextReqTime(0), activeRank(0), timeStampOffset(0)
94{
95 // sanity check the ranks since we rely on bit slicing for the
96 // address decoding
97 fatal_if(!isPowerOf2(ranksPerChannel), "DRAM rank count of %d is not "
98 "allowed, must be a power of two\n", ranksPerChannel);
99
100 fatal_if(!isPowerOf2(burstSize), "DRAM burst size %d is not allowed, "
101 "must be a power of two\n", burstSize);
102
100 for (int i = 0; i < ranksPerChannel; i++) {
101 Rank* rank = new Rank(*this, p);
102 ranks.push_back(rank);
103
104 rank->actTicks.resize(activationLimit, 0);
105 rank->banks.resize(banksPerRank);
106 rank->rank = i;
107

--- 325 unchanged lines hidden (view full) ---

433 unsigned size = std::min((addr | (burstSize - 1)) + 1,
434 pkt->getAddr() + pkt->getSize()) - addr;
435 readPktSize[ceilLog2(size)]++;
436 readBursts++;
437
438 // First check write buffer to see if the data is already at
439 // the controller
440 bool foundInWrQ = false;
103 for (int i = 0; i < ranksPerChannel; i++) {
104 Rank* rank = new Rank(*this, p);
105 ranks.push_back(rank);
106
107 rank->actTicks.resize(activationLimit, 0);
108 rank->banks.resize(banksPerRank);
109 rank->rank = i;
110

--- 325 unchanged lines hidden (view full) ---

436 unsigned size = std::min((addr | (burstSize - 1)) + 1,
437 pkt->getAddr() + pkt->getSize()) - addr;
438 readPktSize[ceilLog2(size)]++;
439 readBursts++;
440
441 // First check write buffer to see if the data is already at
442 // the controller
443 bool foundInWrQ = false;
441 for (auto i = writeQueue.begin(); i != writeQueue.end(); ++i) {
442 // check if the read is subsumed in the write entry we are
443 // looking at
444 if ((*i)->addr <= addr &&
445 (addr + size) <= ((*i)->addr + (*i)->size)) {
446 foundInWrQ = true;
447 servicedByWrQ++;
448 pktsServicedByWrQ++;
449 DPRINTF(DRAM, "Read to addr %lld with size %d serviced by "
450 "write queue\n", addr, size);
451 bytesReadWrQ += burstSize;
452 break;
444 Addr burst_addr = burstAlign(addr);
445 // if the burst address is not present then there is no need
446 // looking any further
447 if (isInWriteQueue.find(burst_addr) != isInWriteQueue.end()) {
448 for (const auto& p : writeQueue) {
449 // check if the read is subsumed in the write queue
450 // packet we are looking at
451 if (p->addr <= addr && (addr + size) <= (p->addr + p->size)) {
452 foundInWrQ = true;
453 servicedByWrQ++;
454 pktsServicedByWrQ++;
455 DPRINTF(DRAM, "Read to addr %lld with size %d serviced by "
456 "write queue\n", addr, size);
457 bytesReadWrQ += burstSize;
458 break;
459 }
453 }
454 }
455
456 // If not found in the write q, make a DRAM packet and
457 // push it onto the read queue
458 if (!foundInWrQ) {
459
460 // Make the burst helper for split packets

--- 51 unchanged lines hidden (view full) ---

512 Addr addr = pkt->getAddr();
513 for (int cnt = 0; cnt < pktCount; ++cnt) {
514 unsigned size = std::min((addr | (burstSize - 1)) + 1,
515 pkt->getAddr() + pkt->getSize()) - addr;
516 writePktSize[ceilLog2(size)]++;
517 writeBursts++;
518
519 // see if we can merge with an existing item in the write
460 }
461 }
462
463 // If not found in the write q, make a DRAM packet and
464 // push it onto the read queue
465 if (!foundInWrQ) {
466
467 // Make the burst helper for split packets

--- 51 unchanged lines hidden (view full) ---

519 Addr addr = pkt->getAddr();
520 for (int cnt = 0; cnt < pktCount; ++cnt) {
521 unsigned size = std::min((addr | (burstSize - 1)) + 1,
522 pkt->getAddr() + pkt->getSize()) - addr;
523 writePktSize[ceilLog2(size)]++;
524 writeBursts++;
525
526 // see if we can merge with an existing item in the write
520 // queue and keep track of whether we have merged or not so we
521 // can stop at that point and also avoid enqueueing a new
522 // request
523 bool merged = false;
524 auto w = writeQueue.begin();
527 // queue and keep track of whether we have merged or not
528 bool merged = isInWriteQueue.find(burstAlign(addr)) !=
529 isInWriteQueue.end();
525
530
526 while(!merged && w != writeQueue.end()) {
527 // either of the two could be first, if they are the same
528 // it does not matter which way we go
529 if ((*w)->addr >= addr) {
530 // the existing one starts after the new one, figure
531 // out where the new one ends with respect to the
532 // existing one
533 if ((addr + size) >= ((*w)->addr + (*w)->size)) {
534 // check if the existing one is completely
535 // subsumed in the new one
536 DPRINTF(DRAM, "Merging write covering existing burst\n");
537 merged = true;
538 // update both the address and the size
539 (*w)->addr = addr;
540 (*w)->size = size;
541 } else if ((addr + size) >= (*w)->addr &&
542 ((*w)->addr + (*w)->size - addr) <= burstSize) {
543 // the new one is just before or partially
544 // overlapping with the existing one, and together
545 // they fit within a burst
546 DPRINTF(DRAM, "Merging write before existing burst\n");
547 merged = true;
548 // the existing queue item needs to be adjusted with
549 // respect to both address and size
550 (*w)->size = (*w)->addr + (*w)->size - addr;
551 (*w)->addr = addr;
552 }
553 } else {
554 // the new one starts after the current one, figure
555 // out where the existing one ends with respect to the
556 // new one
557 if (((*w)->addr + (*w)->size) >= (addr + size)) {
558 // check if the new one is completely subsumed in the
559 // existing one
560 DPRINTF(DRAM, "Merging write into existing burst\n");
561 merged = true;
562 // no adjustments necessary
563 } else if (((*w)->addr + (*w)->size) >= addr &&
564 (addr + size - (*w)->addr) <= burstSize) {
565 // the existing one is just before or partially
566 // overlapping with the new one, and together
567 // they fit within a burst
568 DPRINTF(DRAM, "Merging write after existing burst\n");
569 merged = true;
570 // the address is right, and only the size has
571 // to be adjusted
572 (*w)->size = addr + size - (*w)->addr;
573 }
574 }
575 ++w;
576 }
577
578 // if the item was not merged we need to create a new write
579 // and enqueue it
580 if (!merged) {
581 DRAMPacket* dram_pkt = decodeAddr(pkt, addr, size, false);
582
583 assert(writeQueue.size() < writeBufferSize);
584 wrQLenPdf[writeQueue.size()]++;
585
586 DPRINTF(DRAM, "Adding to write queue\n");
587
588 writeQueue.push_back(dram_pkt);
531 // if the item was not merged we need to create a new write
532 // and enqueue it
533 if (!merged) {
534 DRAMPacket* dram_pkt = decodeAddr(pkt, addr, size, false);
535
536 assert(writeQueue.size() < writeBufferSize);
537 wrQLenPdf[writeQueue.size()]++;
538
539 DPRINTF(DRAM, "Adding to write queue\n");
540
541 writeQueue.push_back(dram_pkt);
542 isInWriteQueue.insert(burstAlign(addr));
543 assert(writeQueue.size() == isInWriteQueue.size());
589
590 // Update stats
591 avgWrQLen = writeQueue.size();
592 } else {
544
545 // Update stats
546 avgWrQLen = writeQueue.size();
547 } else {
548 DPRINTF(DRAM, "Merging write burst with existing queue entry\n");
549
593 // keep track of the fact that this burst effectively
594 // disappeared as it was merged with an existing one
595 mergedWrBursts++;
596 }
597
598 // Starting address of next dram pkt (aligend to burstSize boundary)
599 addr = (addr | (burstSize - 1)) + 1;
600 }

--- 812 unchanged lines hidden (view full) ---

1413 // applied to colAllowedAt
1414 if (switched_cmd_type && dram_pkt->rank == activeRank) {
1415 busBusyUntil += tRTW;
1416 }
1417
1418 doDRAMAccess(dram_pkt);
1419
1420 writeQueue.pop_front();
550 // keep track of the fact that this burst effectively
551 // disappeared as it was merged with an existing one
552 mergedWrBursts++;
553 }
554
555 // Starting address of next dram pkt (aligend to burstSize boundary)
556 addr = (addr | (burstSize - 1)) + 1;
557 }

--- 812 unchanged lines hidden (view full) ---

1370 // applied to colAllowedAt
1371 if (switched_cmd_type && dram_pkt->rank == activeRank) {
1372 busBusyUntil += tRTW;
1373 }
1374
1375 doDRAMAccess(dram_pkt);
1376
1377 writeQueue.pop_front();
1378 isInWriteQueue.erase(burstAlign(dram_pkt->addr));
1421 delete dram_pkt;
1422
1423 // If we emptied the write queue, or got sufficiently below the
1424 // threshold (using the minWritesPerSwitch as the hysteresis) and
1425 // are not draining, or we have reads waiting and have done enough
1426 // writes, then switch to reads.
1427 if (writeQueue.empty() ||
1428 (writeQueue.size() + minWritesPerSwitch < writeLowThreshold &&

--- 860 unchanged lines hidden ---
1379 delete dram_pkt;
1380
1381 // If we emptied the write queue, or got sufficiently below the
1382 // threshold (using the minWritesPerSwitch as the hysteresis) and
1383 // are not draining, or we have reads waiting and have done enough
1384 // writes, then switch to reads.
1385 if (writeQueue.empty() ||
1386 (writeQueue.size() + minWritesPerSwitch < writeLowThreshold &&

--- 860 unchanged lines hidden ---