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