From 31101a0827a178dce92cf825e0d4d1d59fa84048 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 14 Aug 2019 20:19:27 +0200 Subject: [PATCH] Finished bankwise refresh. --- DRAMSys/library/src/controller/Command.cpp | 5 +- .../library/src/controller/ControllerNew.cpp | 8 +++ .../src/controller/checker/CheckerDDR3.cpp | 49 +++++++++++++++++-- .../src/controller/checker/CheckerDDR3.h | 23 ++++++--- .../controller/core/configuration/MemSpec.cpp | 2 + .../refresh/RefreshManagerBankwise.cpp | 31 ++++++++++-- .../refresh/RefreshManagerBankwise.h | 1 + 7 files changed, 103 insertions(+), 16 deletions(-) diff --git a/DRAMSys/library/src/controller/Command.cpp b/DRAMSys/library/src/controller/Command.cpp index fc2474ce..bfef86c0 100644 --- a/DRAMSys/library/src/controller/Command.cpp +++ b/DRAMSys/library/src/controller/Command.cpp @@ -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 &getAllCommands() Command::RDA, Command::WRA, Command::REFA, + Command::REFB, Command::PDEA, Command::PDXA, Command::PDEP, diff --git a/DRAMSys/library/src/controller/ControllerNew.cpp b/DRAMSys/library/src/controller/ControllerNew.cpp index 8ca1dfa2..82d8074a 100644 --- a/DRAMSys/library/src/controller/ControllerNew.cpp +++ b/DRAMSys/library/src/controller/ControllerNew.cpp @@ -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"); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp index a3672e16..9fe18c8c 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp @@ -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; } diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.h b/DRAMSys/library/src/controller/checker/CheckerDDR3.h index ab3bceec..7357bdee 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.h @@ -37,6 +37,7 @@ #include "CheckerIF.h" #include +#include #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 timesForNextREFB; + std::map timesForNextPRE; +}; #endif // CHECKERDDR3_H diff --git a/DRAMSys/library/src/controller/core/configuration/MemSpec.cpp b/DRAMSys/library/src/controller/core/configuration/MemSpec.cpp index 9b01d316..5d8f970c 100644 --- a/DRAMSys/library/src/controller/core/configuration/MemSpec.cpp +++ b/DRAMSys/library/src/controller/core/configuration/MemSpec.cpp @@ -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) diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp index 93dbe4b6..2c978461 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp @@ -44,10 +44,12 @@ RefreshManagerBankwise::RefreshManagerBankwise(std::map &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(currentREFB, Bank(bankID))); triggerTimes.insert(std::pair(currentPRE, Bank(bankID))); @@ -58,10 +60,33 @@ RefreshManagerBankwise::RefreshManagerBankwise(std::map &ba std::pair RefreshManagerBankwise::getNextCommand() { - + if (sc_time_stamp() == timeForNextTrigger) + { + auto it = triggerTimes.begin(); + Bank bank = it->second; + triggerTimes.erase(it); + triggerTimes.insert(std::pair(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::PRE, &refreshPayloads[bank]); + else + return std::pair(Command::NOP, nullptr); + } + else + { + states[bank] = RmState::IDLE; + return std::pair(Command::REFB, &refreshPayloads[bank]); + } + } + else + return std::pair(Command::NOP, nullptr); } sc_time RefreshManagerBankwise::getTriggerDelay() { - + return timeForNextTrigger - sc_time_stamp(); } diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h index 08758631..c38d56bd 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h @@ -54,6 +54,7 @@ private: std::map &bankMachines; std::map refreshPayloads; std::map triggerTimes; + sc_time timeForNextTrigger; enum class RmState {IDLE, REFRESHING}; std::map states; };