Finished bankwise refresh.

This commit is contained in:
Lukas Steiner
2019-08-14 20:19:27 +02:00
parent 47ee187bc3
commit 31101a0827
7 changed files with 103 additions and 16 deletions

View File

@@ -72,7 +72,9 @@ std::string commandToString(Command command)
case Command::REFA:
return "REFA";
break;
case Command::REFB:
return "REFB";
break;
case Command::PDEA:
return "PDEA";
break;
@@ -116,6 +118,7 @@ const std::vector<Command> &getAllCommands()
Command::RDA,
Command::WRA,
Command::REFA,
Command::REFB,
Command::PDEA,
Command::PDXA,
Command::PDEP,

View File

@@ -45,6 +45,7 @@
#include "checker/CheckerDDR3.h"
#include "refresh/RefreshManager.h"
#include "refresh/RefreshManagerDummy.h"
#include "refresh/RefreshManagerBankwise.h"
ControllerNew::ControllerNew(sc_module_name name) :
GenericController(name)
@@ -59,6 +60,11 @@ ControllerNew::ControllerNew(sc_module_name name) :
checker = new CheckerDDR3();
if (config.ControllerCoreRefDisable)
refreshManager = new RefreshManagerDummy();
else if (config.BankwiseLogic)
{
refreshManager = new RefreshManagerBankwise(bankMachines);
refreshEvent.notify(refreshManager->getTriggerDelay());
}
else
{
refreshManager = new RefreshManager(bankMachines);
@@ -266,6 +272,8 @@ void ControllerNew::sendToDram(Command command, tlm_generic_payload *payload)
phase = BEGIN_PRE_ALL;
else if (command == Command::REFA)
phase = BEGIN_REFA;
else if (command == Command::REFB)
phase = BEGIN_REFB;
else
SC_REPORT_FATAL("ControllerNew", "Unknown phase");

View File

@@ -43,8 +43,8 @@ CheckerDDR3::CheckerDDR3()
if (config.ControllerCoreRefDisable)
refreshChecker = new RefreshCheckerDummy();
// else if (config.BankwiseLogic)
// refreshChecker = new RefreshCheckerBankwise();
else if (config.BankwiseLogic)
refreshChecker = new RefreshCheckerBankwise();
else
refreshChecker = new RefreshChecker();
}
@@ -86,6 +86,10 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Bank bank)
if (lastCommand.isValidCommand())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tRFC);
lastCommand = lastScheduledByCommandAndBank[Command::REFB][bank];
if (lastCommand.isValidCommand())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tRFC);
earliestTimeToStart = std::max(earliestTimeToStart, timeToSatisfyFAW());
refreshChecker->delayForACT(bank, earliestTimeToStart);
@@ -179,7 +183,7 @@ void CheckerDDR3::insert(const ScheduledCommand &scheduledCommand)
lastActivates.pop();
lastActivates.push(scheduledCommand.getStart());
}
else if (command == Command::REFA)
else if (command == Command::REFA || command == Command::REFB)
refreshChecker->insert(bank);
}
@@ -211,5 +215,42 @@ void RefreshChecker::delayForPRE(const Bank &, sc_time &earliestTimeToStart)
void RefreshChecker::insert(const Bank &)
{
timeForNextREFA += memSpec->tREFI;
timeForNextPREA = timeForNextREFA - memSpec->tRP;
timeForNextPREA += memSpec->tREFI;
}
RefreshCheckerBankwise::RefreshCheckerBankwise()
{
sc_time currentREFB = memSpec->tREFI - memSpec->clk * (memSpec->NumberOfBanks - 1);
sc_time currentPRE = currentREFB - std::max(memSpec->clk * memSpec->NumberOfBanks, memSpec->tRP);
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
{
timesForNextREFB[Bank(bankID)] = currentREFB;
timesForNextPRE[Bank(bankID)] = currentPRE;
currentREFB += memSpec->clk;
currentPRE += memSpec->clk;
}
}
void RefreshCheckerBankwise::delayForACT(const Bank &bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= (timesForNextPRE[bank] - memSpec->tRAS))
earliestTimeToStart = timesForNextREFB[bank] + memSpec->tRFC;
}
void RefreshCheckerBankwise::delayForRD(const Bank &bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= (timesForNextPRE[bank] - memSpec->tRTP))
earliestTimeToStart = timesForNextREFB[bank] + memSpec->tRFC;
}
void RefreshCheckerBankwise::delayForWR(const Bank &bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= (timesForNextPRE[bank] - memSpec->tWL - memSpec->tCCD - memSpec->tWR))
earliestTimeToStart = timesForNextREFB[bank] + memSpec->tRFC;
}
void RefreshCheckerBankwise::insert(const Bank &bank)
{
timesForNextREFB[bank] += memSpec->tREFI;
timesForNextPRE[bank] += memSpec->tREFI;
}

View File

@@ -37,6 +37,7 @@
#include "CheckerIF.h"
#include <queue>
#include <map>
#include "../core/configuration/MemSpec.h"
#include "../core/configuration/Configuration.h"
@@ -117,14 +118,20 @@ private:
sc_time timeForNextPREA = timeForNextREFA - memSpec->tRP;
};
//class RefreshCheckerBankwise final : public RefreshCheckerIF
//{
//private:
// friend class CheckerDDR3;
// RefreshCheckerBankwise() {}
class RefreshCheckerBankwise final : public RefreshCheckerIF
{
private:
friend class CheckerDDR3;
RefreshCheckerBankwise();
// void delayToSatisfyConstraints(const Command &, const Bank &, sc_time &);
// void insert(const Command &, const Bank &);
//};
void delayForACT(const Bank &, sc_time &);
void delayForRD(const Bank &, sc_time &);
void delayForWR(const Bank &, sc_time &);
void delayForPRE(const Bank &, sc_time &) {}
void insert(const Bank &);
std::map<Bank, sc_time> timesForNextREFB;
std::map<Bank, sc_time> timesForNextPRE;
};
#endif // CHECKERDDR3_H

View File

@@ -96,6 +96,8 @@ sc_time MemSpec::getExecutionTime(Command command, tlm::tlm_generic_payload &pay
else if (command == Command::PREA)
return tRP_old;
else if (command == Command::REFA)
return tRFC_old;
else if (command == Command::REFB)
return getElementFromMap(refreshTimings,
DramExtension::getExtension(payload).getBank()).tRFC;
else if (command == Command::PDXA || command == Command::PDXP || command == Command::SREFEX)

View File

@@ -44,10 +44,12 @@ RefreshManagerBankwise::RefreshManagerBankwise(std::map<Bank, BankMachine *> &ba
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
sc_time currentREFB = memSpec->tREFI - memSpec->clk * memSpec->NumberOfBanks;
sc_time currentREFB = memSpec->tREFI - memSpec->clk * (memSpec->NumberOfBanks - 1);
sc_time currentPRE = currentREFB - std::max(memSpec->clk * memSpec->NumberOfBanks, memSpec->tRP);
timeForNextTrigger = currentPRE;
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
{
states[Bank(bankID)] = RmState::IDLE;
setUpDummy(refreshPayloads[Bank(bankID)], Bank(bankID));
triggerTimes.insert(std::pair<sc_time, Bank>(currentREFB, Bank(bankID)));
triggerTimes.insert(std::pair<sc_time, Bank>(currentPRE, Bank(bankID)));
@@ -58,10 +60,33 @@ RefreshManagerBankwise::RefreshManagerBankwise(std::map<Bank, BankMachine *> &ba
std::pair<Command, tlm_generic_payload *> RefreshManagerBankwise::getNextCommand()
{
if (sc_time_stamp() == timeForNextTrigger)
{
auto it = triggerTimes.begin();
Bank bank = it->second;
triggerTimes.erase(it);
triggerTimes.insert(std::pair<sc_time, Bank>(timeForNextTrigger + memSpec->tREFI, bank));
timeForNextTrigger = triggerTimes.begin()->first;
if (states[bank] == RmState::IDLE)
{
states[bank] = RmState::REFRESHING;
bool forcedPrecharge = bankMachines[bank]->forcePrecharge();
if (forcedPrecharge)
return std::pair<Command, tlm_generic_payload *>(Command::PRE, &refreshPayloads[bank]);
else
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
}
else
{
states[bank] = RmState::IDLE;
return std::pair<Command, tlm_generic_payload *>(Command::REFB, &refreshPayloads[bank]);
}
}
else
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
}
sc_time RefreshManagerBankwise::getTriggerDelay()
{
return timeForNextTrigger - sc_time_stamp();
}

View File

@@ -54,6 +54,7 @@ private:
std::map<Bank, BankMachine *> &bankMachines;
std::map<Bank, tlm_generic_payload> refreshPayloads;
std::map<sc_time, Bank> triggerTimes;
sc_time timeForNextTrigger;
enum class RmState {IDLE, REFRESHING};
std::map<Bank, RmState> states;
};