diff -r 5e8970397ab7 src/mem/SimpleDRAM.py --- a/src/mem/SimpleDRAM.py Fri Nov 01 11:56:19 2013 -0400 +++ b/src/mem/SimpleDRAM.py Fri Dec 06 12:04:27 2013 +0100 @@ -110,6 +110,7 @@ # the time from issuing a read/write command to seeing the actual data tCL = Param.Latency("CAS latency") + tCL_write = Param.Latency("CAS latency for write operation") # minimum time between a precharge and subsequent activate tRP = Param.Latency("Row precharge time") @@ -171,6 +172,7 @@ # DDR3-1600 11-11-11 tRCD = '13.75ns' tCL = '13.75ns' + tCL_write = '13.75ns' tRP = '13.75ns' tRAS = '41.25ns' @@ -220,6 +222,7 @@ # 8 CK read latency, 4 CK write latency @ 533 MHz, 1.876 ns cycle time tCL = '15ns' + tCL_write = '15ns' # Pre-charge one bank 15 ns (all banks 18 ns) tRP = '15ns' @@ -268,6 +271,7 @@ # WIO-200 tRCD = '18ns' tCL = '18ns' + tCL_write = '18ns' tRP = '18ns' tRAS = '54ns' @@ -316,6 +320,7 @@ # 12 CK read latency, 6 CK write latency @ 800 MHz, 1.25 ns cycle time tCL = '15ns' + tCL_write = '15ns' tRAS = '45ns' diff -r 5e8970397ab7 src/mem/simple_dram.hh --- a/src/mem/simple_dram.hh Fri Nov 01 11:56:19 2013 -0400 +++ b/src/mem/simple_dram.hh Fri Dec 06 12:04:27 2013 +0100 @@ -464,6 +464,7 @@ const Tick tBURST; const Tick tRCD; const Tick tCL; + const Tick tCL_write; const Tick tRP; const Tick tRAS; const Tick tRFC; diff -r 5e8970397ab7 src/mem/simple_dram.cc --- a/src/mem/simple_dram.cc Fri Nov 01 11:56:19 2013 -0400 +++ b/src/mem/simple_dram.cc Fri Dec 06 12:04:27 2013 +0100 @@ -67,7 +67,8 @@ writeBufferSize(p->write_buffer_size), writeThresholdPerc(p->write_thresh_perc), tWTR(p->tWTR), tBURST(p->tBURST), - tRCD(p->tRCD), tCL(p->tCL), tRP(p->tRP), tRAS(p->tRAS), + tRCD(p->tRCD), tCL(p->tCL), tCL_write(p->tCL_write), + tRP(p->tRP), tRAS(p->tRAS), tRFC(p->tRFC), tREFI(p->tREFI), tXAW(p->tXAW), activationLimit(p->activation_limit), memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping), @@ -161,6 +162,11 @@ // this value is not supposed to be accurate, just enough to // keep things going, mimic a closed page latency = tRP + tRCD + tCL; + + // Update if it is a write operation + if(pkt->isWrite()) { + latency = tRP + tRCD + tCL_write; + } } return latency; } @@ -605,13 +611,15 @@ DPRINTF(DRAM, "Memory controller %s timing specs\n" \ "tRCD %d ticks\n" \ "tCL %d ticks\n" \ + "tCL_write %d ticks\n" \ "tRP %d ticks\n" \ "tBURST %d ticks\n" \ "tRFC %d ticks\n" \ "tREFI %d ticks\n" \ "tWTR %d ticks\n" \ "tXAW (%d) %d ticks\n", - name(), tRCD, tCL, tRP, tBURST, tRFC, tREFI, tWTR, + name(), tRCD, tCL, tCL_write, tRP, + tBURST, tRFC, tREFI, tWTR, activationLimit, tXAW); } @@ -902,15 +910,24 @@ // busy and a new request comes in, it can be completed with no // penalty beyond waiting for the existing read to complete. if (bank.freeAt > inTime) { + DPRINTF(DRAM, "Row hit, Bank not free (request %lld)\n", + dram_pkt->addr); accLat += bank.freeAt - inTime; bankLat += 0; } else { - // CAS latency only - accLat += tCL; - bankLat += tCL; + // CAS latency only (check if it is read or write) + DPRINTF(DRAM, "Row hit, Bank free, CAS latency only (request %lld)\n", dram_pkt->addr); + if(dram_pkt->isRead) { + accLat += tCL; + bankLat += tCL; + } else { + accLat += tCL_write; + bankLat += tCL_write; + } } } else { + DPRINTF(DRAM, "Row miss (request %lld)\n", dram_pkt->addr); // Row-buffer miss, need to close existing row // once tRAS has expired, then open the new one, // then add cas latency. @@ -919,8 +936,14 @@ if (freeTime > inTime) accLat += freeTime - inTime; - accLat += tRP + tRCD + tCL; - bankLat += tRP + tRCD + tCL; + // Check if it is read or write + if(dram_pkt->isRead) { + accLat += tRP + tRCD + tCL; + bankLat += tRP + tRCD + tCL; + } else { + accLat += tRP + tRCD + tCL_write; + bankLat += tRP + tRCD + tCL_write; + } } } else if (pageMgmt == Enums::close) { // With a close page policy, no notion of @@ -929,9 +952,14 @@ accLat += bank.freeAt - inTime; // page already closed, simply open the row, and - // add cas latency - accLat += tRCD + tCL; - bankLat += tRCD + tCL; + // add cas latency (check if it is read or write) + if(dram_pkt->isRead) { + accLat += tRCD + tCL; + bankLat += tRCD + tCL; + } else { + accLat += tRCD + tCL_write; + bankLat += tRCD + tCL_write; + } } else panic("No page management policy chosen\n"); @@ -1021,6 +1049,10 @@ if (!rowHitFlag) { // any waiting for banks account for in freeAt actTick = bank.freeAt - tCL - tRCD; + // Update actTick if it is a write operation + if(!dram_pkt->isRead) { + actTick = bank.freeAt - tCL_write - tRCD; + } bank.tRASDoneAt = actTick + tRAS; recordActivate(actTick); @@ -1031,6 +1063,10 @@ } } else if (pageMgmt == Enums::close) { actTick = curTick() + addDelay + accessLat - tRCD - tCL; + // Update actTick if it is a write operation + if(!dram_pkt->isRead) { + actTick = curTick() + addDelay + accessLat - tRCD - tCL_write; + } recordActivate(actTick); // If the DRAM has a very quick tRAS, bank can be made free @@ -1038,6 +1074,10 @@ // an additional wait is required to respect tRAS. bank.freeAt = std::max(actTick + tRAS + tRP, actTick + tRCD + tCL + tRP); + // Update bank.freeAt if it is a write operation + if(!dram_pkt->isRead) { + bank.freeAt = std::max(actTick + tRAS + tRP, actTick + tRCD + tCL + tRP); + } DPRINTF(DRAM,"doDRAMAccess::bank.freeAt is %lld\n",bank.freeAt); bytesPerActivate.sample(burstSize); @@ -1101,6 +1141,13 @@ std::max(busBusyUntil - (tRP + tRCD + tCL) , curTick()) : curTick(); + // Update newTime if it is a write operation + if(!dram_pkt->isRead) { + newTime = (busBusyUntil > tRP + tRCD + tCL_write ) ? + std::max(busBusyUntil - (tRP + tRCD + tCL_write) , curTick()) : + curTick(); + } + if (!nextReqEvent.scheduled() && !stopReads){ schedule(nextReqEvent, newTime); } else {