* Ani Udipi
*/
+#include "base/trace.hh"
+#include "debug/Drain.hh"
#include "debug/DRAM.hh"
#include "debug/DRAMWR.hh"
#include "mem/simple_dram.hh"
bool
SimpleDRAM::recvTimingReq(PacketPtr pkt)
{
+ /// @todo temporary hack to deal with memory corruption issues until
+ /// 4-phase transactions are complete
+ for (int x = 0; x < pendingDelete.size(); x++)
+ delete pendingDelete[x];
+ pendingDelete.clear();
+
+
// This is where we enter from the outside world
DPRINTF(DRAM, "Inside recvTimingReq: request %s addr %lld size %d\n",
pkt->cmdString(),pkt->getAddr(), pkt->getSize());
// simply drop inhibited packets for now
if (pkt->memInhibitAsserted()) {
DPRINTF(DRAM,"Inhibited packet -- Dropping it now\n");
- delete pkt;
+ pendingDelete.push_back(pkt);
return true;
}
DPRINTF(DRAM, "Reached scheduleNextReq()\n");
// Figure out which request goes next, and move it to front()
- if (!chooseNextReq())
- return;
-
- doDRAMAccess(dramReadQueue.front());
+ if (!chooseNextReq()) {
+ // In the case there is no read request to go next, see if we
+ // are asked to drain, and if so trigger writes, this also
+ // ensures that if we hit the write limit we will do this
+ // multiple times until we are completely drained
+ if (drainManager && !dramWriteQueue.empty() && !writeEvent.scheduled())
+ triggerWrites();
+ } else {
+ doDRAMAccess(dramReadQueue.front());
+ }
}
-
-
-
Tick
SimpleDRAM::maxBankFreeAt() const
{
// of that as well
if (!(dramWriteQueue.empty() && dramReadQueue.empty() &&
dramRespQueue.empty())) {
+ DPRINTF(Drain, "DRAM controller not drained, write: %d, read: %d,"
+ " resp: %d\n", dramWriteQueue.size(), dramReadQueue.size(),
+ dramRespQueue.size());
++count;
drainManager = dm;
+ // the only part that is not drained automatically over time
+ // is the write queue, thus trigger writes if there are any
+ // waiting and no reads waiting, otherwise wait until the
+ // reads are done
+ if (dramReadQueue.empty() && !dramWriteQueue.empty() &&
+ !writeEvent.scheduled())
+ triggerWrites();
}
if (count)