mem: Fix DRAM draining to ensure write queue is empty
This patch fixes the draining of the SimpleDRAM controller model. The controller performs buffering of writes and normally there is no need to ever empty the write buffer (if you have a fast on-chip memory, then use it). The patch adds checks to ensure the write buffer is drained when the controller is asked to do so.
This commit is contained in:
parent
bb4f6562ae
commit
c4b36901d0
1 changed files with 21 additions and 7 deletions
|
@ -38,6 +38,7 @@
|
||||||
* Ani Udipi
|
* Ani Udipi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "debug/Drain.hh"
|
||||||
#include "debug/DRAM.hh"
|
#include "debug/DRAM.hh"
|
||||||
#include "debug/DRAMWR.hh"
|
#include "debug/DRAMWR.hh"
|
||||||
#include "mem/simple_dram.hh"
|
#include "mem/simple_dram.hh"
|
||||||
|
@ -934,15 +935,18 @@ SimpleDRAM::scheduleNextReq()
|
||||||
DPRINTF(DRAM, "Reached scheduleNextReq()\n");
|
DPRINTF(DRAM, "Reached scheduleNextReq()\n");
|
||||||
|
|
||||||
// Figure out which request goes next, and move it to front()
|
// Figure out which request goes next, and move it to front()
|
||||||
if (!chooseNextReq())
|
if (!chooseNextReq()) {
|
||||||
return;
|
// 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
|
||||||
doDRAMAccess(dramReadQueue.front());
|
// 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
|
Tick
|
||||||
SimpleDRAM::maxBankFreeAt() const
|
SimpleDRAM::maxBankFreeAt() const
|
||||||
{
|
{
|
||||||
|
@ -1212,8 +1216,18 @@ SimpleDRAM::drain(DrainManager *dm)
|
||||||
// of that as well
|
// of that as well
|
||||||
if (!(dramWriteQueue.empty() && dramReadQueue.empty() &&
|
if (!(dramWriteQueue.empty() && dramReadQueue.empty() &&
|
||||||
dramRespQueue.empty())) {
|
dramRespQueue.empty())) {
|
||||||
|
DPRINTF(Drain, "DRAM controller not drained, write: %d, read: %d,"
|
||||||
|
" resp: %d\n", dramWriteQueue.size(), dramReadQueue.size(),
|
||||||
|
dramRespQueue.size());
|
||||||
++count;
|
++count;
|
||||||
drainManager = dm;
|
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)
|
if (count)
|
||||||
|
|
Loading…
Reference in a new issue