Deleted Added
sdiff udiff text old ( 12084:5a3769ff3d55 ) new ( 12266:63b8da9eeca4 )
full compact
1/*
2 * Copyright (c) 2010-2017 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

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

37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Andreas Hansson
41 * Ani Udipi
42 * Neha Agarwal
43 * Omar Naji
44 * Wendy Elsasser
45 */
46
47#include "mem/dram_ctrl.hh"
48
49#include "base/bitfield.hh"
50#include "base/trace.hh"
51#include "debug/DRAM.hh"
52#include "debug/DRAMPower.hh"

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

89 tRRD_L(p->tRRD_L), tXAW(p->tXAW), tXP(p->tXP), tXS(p->tXS),
90 activationLimit(p->activation_limit),
91 memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping),
92 pageMgmt(p->page_policy),
93 maxAccessesPerRow(p->max_accesses_per_row),
94 frontendLatency(p->static_frontend_latency),
95 backendLatency(p->static_backend_latency),
96 busBusyUntil(0), prevArrival(0),
97 nextReqTime(0), activeRank(0), timeStampOffset(0)
98{
99 // sanity check the ranks since we rely on bit slicing for the
100 // address decoding
101 fatal_if(!isPowerOf2(ranksPerChannel), "DRAM rank count of %d is not "
102 "allowed, must be a power of two\n", ranksPerChannel);
103
104 fatal_if(!isPowerOf2(burstSize), "DRAM burst size %d is not allowed, "
105 "must be a power of two\n", burstSize);

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

737 // FCFS, this method does nothing
738 assert(!queue.empty());
739
740 // bool to indicate if a packet to an available rank is found
741 bool found_packet = false;
742 if (queue.size() == 1) {
743 DRAMPacket* dram_pkt = queue.front();
744 // available rank corresponds to state refresh idle
745 if (ranks[dram_pkt->rank]->isAvailable()) {
746 found_packet = true;
747 DPRINTF(DRAM, "Single request, going to a free rank\n");
748 } else {
749 DPRINTF(DRAM, "Single request, going to a busy rank\n");
750 }
751 return found_packet;
752 }
753
754 if (memSchedPolicy == Enums::fcfs) {
755 // check if there is a packet going to a free rank
756 for (auto i = queue.begin(); i != queue.end() ; ++i) {
757 DRAMPacket* dram_pkt = *i;
758 if (ranks[dram_pkt->rank]->isAvailable()) {
759 queue.erase(i);
760 queue.push_front(dram_pkt);
761 found_packet = true;
762 break;
763 }
764 }
765 } else if (memSchedPolicy == Enums::frfcfs) {
766 found_packet = reorderQueue(queue, extra_col_delay);

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

796 // time we need to issue a column command to be seamless
797 const Tick min_col_at = std::max(busBusyUntil - tCL + extra_col_delay,
798 curTick());
799
800 for (auto i = queue.begin(); i != queue.end() ; ++i) {
801 DRAMPacket* dram_pkt = *i;
802 const Bank& bank = dram_pkt->bankRef;
803
804 // check if rank is available, if not, jump to the next packet
805 if (dram_pkt->rankRef.isAvailable()) {
806 // check if it is a row hit
807 if (bank.openRow == dram_pkt->row) {
808 // no additional rank-to-rank or same bank-group
809 // delays, or we switched read/write and might as well
810 // go for the row hit
811 if (bank.colAllowedAt <= min_col_at) {
812 // FCFS within the hits, giving priority to
813 // commands that can issue seamlessly, without

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

1263 }
1264}
1265
1266void
1267DRAMCtrl::processNextReqEvent()
1268{
1269 int busyRanks = 0;
1270 for (auto r : ranks) {
1271 if (!r->isAvailable()) {
1272 if (r->pwrState != PWR_SREF) {
1273 // rank is busy refreshing
1274 DPRINTF(DRAMState, "Rank %d is not available\n", r->rank);
1275 busyRanks++;
1276
1277 // let the rank know that if it was waiting to drain, it
1278 // is now done and ready to proceed
1279 r->checkDrainDone();

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

1380 // at this point. There could be writes to the available ranks
1381 // which are above the required threshold. However, to
1382 // avoid adding more complexity to the code, return and wait
1383 // for a refresh event to kick things into action again.
1384 if (!found_read)
1385 return;
1386
1387 DRAMPacket* dram_pkt = readQueue.front();
1388 assert(dram_pkt->rankRef.isAvailable());
1389
1390 // here we get a bit creative and shift the bus busy time not
1391 // just the tWTR, but also a CAS latency to capture the fact
1392 // that we are allowed to prepare a new bank, but not issue a
1393 // read command until after tWTR, in essence we capture a
1394 // bubble on the data bus that is tWTR + tCL
1395 if (switched_cmd_type && dram_pkt->rank == activeRank) {
1396 busBusyUntil += tWTR + tCL;

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

1437 // bool to check if write to free rank is found
1438 bool found_write = false;
1439
1440 // If we are changing command type, incorporate the minimum
1441 // bus turnaround delay
1442 found_write = chooseNext(writeQueue,
1443 switched_cmd_type ? std::min(tRTW, tCS) : 0);
1444
1445 // if no writes to an available rank are found then return.
1446 // There could be reads to the available ranks. However, to avoid
1447 // adding more complexity to the code, return at this point and wait
1448 // for a refresh event to kick things into action again.
1449 if (!found_write)
1450 return;
1451
1452 DRAMPacket* dram_pkt = writeQueue.front();
1453 assert(dram_pkt->rankRef.isAvailable());
1454 // sanity check
1455 assert(dram_pkt->size <= burstSize);
1456
1457 // add a bubble to the data bus, as defined by the
1458 // tRTW when access is to the same rank as previous burst
1459 // Different rank timing is handled with tCS, which is
1460 // applied to colAllowedAt
1461 if (switched_cmd_type && dram_pkt->rank == activeRank) {

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

1537 // Flag condition when bank can be opened without incurring additional
1538 // delay on the data bus
1539 bool hidden_bank_prep = false;
1540
1541 // determine if we have queued transactions targetting the
1542 // bank in question
1543 vector<bool> got_waiting(ranksPerChannel * banksPerRank, false);
1544 for (const auto& p : queue) {
1545 if (p->rankRef.isAvailable())
1546 got_waiting[p->bankId] = true;
1547 }
1548
1549 // Find command with optimal bank timing
1550 // Will prioritize commands that can issue seamlessly.
1551 for (int i = 0; i < ranksPerChannel; i++) {
1552 for (int j = 0; j < banksPerRank; j++) {
1553 uint16_t bank_id = i * banksPerRank + j;
1554
1555 // if we have waiting requests for the bank, and it is
1556 // amongst the first available, update the mask
1557 if (got_waiting[bank_id]) {
1558 // make sure this rank is not currently refreshing.
1559 assert(ranks[i]->isAvailable());
1560 // simplistic approximation of when the bank can issue
1561 // an activate, ignoring any rank-to-rank switching
1562 // cost in this calculation
1563 Tick act_at = ranks[i]->banks[j].openRow == Bank::NO_ROW ?
1564 std::max(ranks[i]->banks[j].actAllowedAt, curTick()) :
1565 std::max(ranks[i]->banks[j].preAllowedAt, curTick()) + tRP;
1566
1567 // When is the earliest the R/W burst can issue?

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

2173
2174 // go back to REF event and close banks
2175 refreshState = REF_PRE;
2176 schedule(refreshEvent, curTick());
2177 }
2178 } else if (pwrState == PWR_IDLE) {
2179 DPRINTF(DRAMState, "All banks precharged\n");
2180 if (prev_state == PWR_SREF) {
2181 // set refresh state to REF_SREF_EXIT, ensuring isAvailable
2182 // continues to return false during tXS after SREF exit
2183 // Schedule a refresh which kicks things back into action
2184 // when it finishes
2185 refreshState = REF_SREF_EXIT;
2186 schedule(refreshEvent, curTick() + memory.tXS);
2187 } else {
2188 // if we have a pending refresh, and are now moving to
2189 // the idle state, directly transition to a refresh

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

2230
2231void
2232DRAMCtrl::Rank::updatePowerStats()
2233{
2234 // All commands up to refresh have completed
2235 // flush cmdList to DRAMPower
2236 flushCmdList();
2237
2238 // update the counters for DRAMPower, passing false to
2239 // indicate that this is not the last command in the
2240 // list. DRAMPower requires this information for the
2241 // correct calculation of the background energy at the end
2242 // of the simulation. Ideally we would want to call this
2243 // function with true once at the end of the
2244 // simulation. However, the discarded energy is extremly
2245 // small and does not effect the final results.
2246 power.powerlib.updateCounters(false);
2247
2248 // call the energy function
2249 power.powerlib.calcEnergy();
2250
2251 // Get the energy and power from DRAMPower
2252 Data::MemoryPowerModel::Energy energy =
2253 power.powerlib.getEnergy();
2254 Data::MemoryPowerModel::Power rank_power =
2255 power.powerlib.getPower();
2256
2257 actEnergy = energy.act_energy * memory.devicesPerRank;
2258 preEnergy = energy.pre_energy * memory.devicesPerRank;
2259 readEnergy = energy.read_energy * memory.devicesPerRank;
2260 writeEnergy = energy.write_energy * memory.devicesPerRank;
2261 refreshEnergy = energy.ref_energy * memory.devicesPerRank;
2262 actBackEnergy = energy.act_stdby_energy * memory.devicesPerRank;
2263 preBackEnergy = energy.pre_stdby_energy * memory.devicesPerRank;
2264 actPowerDownEnergy = energy.f_act_pd_energy * memory.devicesPerRank;
2265 prePowerDownEnergy = energy.f_pre_pd_energy * memory.devicesPerRank;
2266 selfRefreshEnergy = energy.sref_energy * memory.devicesPerRank;
2267 totalEnergy = energy.total_energy * memory.devicesPerRank;
2268 averagePower = rank_power.average_power * memory.devicesPerRank;
2269}
2270
2271void
2272DRAMCtrl::Rank::computeStats()
2273{
2274 DPRINTF(DRAM,"Computing final stats\n");
2275
2276 // Force DRAM power to update counters based on time spent in
2277 // current state up to curTick()
2278 cmdList.push_back(Command(MemCommand::NOP, 0, curTick()));
2279
2280 // Update the stats
2281 updatePowerStats();
2282
2283 // final update of power state times
2284 pwrStateTime[pwrState] += (curTick() - pwrStateTick);
2285 pwrStateTick = curTick();
2286
2287}
2288
2289void
2290DRAMCtrl::Rank::regStats()
2291{
2292 using namespace Stats;
2293
2294 pwrStateTime
2295 .init(6)
2296 .name(name() + ".memoryStateTime")
2297 .desc("Time in different power states");

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

2350 .name(name() + ".averagePower")
2351 .desc("Core power per rank (mW)");
2352
2353 totalIdleTime
2354 .name(name() + ".totalIdleTime")
2355 .desc("Total Idle time Per DRAM Rank");
2356
2357 registerDumpCallback(new RankDumpCallback(this));
2358}
2359void
2360DRAMCtrl::regStats()
2361{
2362 using namespace Stats;
2363
2364 AbstractMemory::regStats();
2365
2366 for (auto r : ranks) {
2367 r->regStats();
2368 }
2369
2370 readReqs
2371 .name(name() + ".readReqs")
2372 .desc("Number of read requests accepted");
2373
2374 writeReqs
2375 .name(name() + ".writeReqs")
2376 .desc("Number of write requests accepted");
2377

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

2667}
2668
2669bool
2670DRAMCtrl::allRanksDrained() const
2671{
2672 // true until proven false
2673 bool all_ranks_drained = true;
2674 for (auto r : ranks) {
2675 // then verify that the power state is IDLE
2676 // ensuring all banks are closed and rank is not in a low power state
2677 all_ranks_drained = r->inPwrIdleState() && all_ranks_drained;
2678 }
2679 return all_ranks_drained;
2680}
2681
2682void
2683DRAMCtrl::drainResume()
2684{
2685 if (!isTimingMode && system()->isTimingMode()) {

--- 61 unchanged lines hidden ---