Finished bankwise refresh.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user