First part of same bank refresh (manager not done).
This commit is contained in:
@@ -137,6 +137,7 @@ add_library(DRAMSysLibrary
|
||||
src/controller/refresh/RefreshManagerDummy.cpp
|
||||
src/controller/refresh/RefreshManagerRankwise.cpp
|
||||
src/controller/refresh/RefreshManagerBankwise.cpp
|
||||
src/controller/refresh/RefreshManagerGroupwise.cpp
|
||||
|
||||
src/controller/respqueue/RespQueueIF.h
|
||||
src/controller/respqueue/RespQueueFifo.cpp
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"RCD": 22,
|
||||
"REFM": 1,
|
||||
"REFI": 6240,
|
||||
"REFISB": 1560,
|
||||
"RFC": 312,
|
||||
"RL": 22,
|
||||
"RPRE": 1,
|
||||
|
||||
@@ -50,7 +50,8 @@
|
||||
"RFC_dpr": 104,
|
||||
"RFCsb_slr": 184,
|
||||
"RFCsb_dlr": 62,
|
||||
"REFI": 6240,
|
||||
"REFI": 6240,
|
||||
"REFISB": 1560,
|
||||
"REFSBRD_slr": 48,
|
||||
"REFSBRD_dlr": 24,
|
||||
"RTRS": 2,
|
||||
|
||||
@@ -74,3 +74,21 @@ sc_time MemSpec::getCommandLength(Command command) const
|
||||
{
|
||||
return tCK * commandLengthInCycles[command];
|
||||
}
|
||||
|
||||
sc_time MemSpec::getRefreshIntervalAB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "All bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
sc_time MemSpec::getRefreshIntervalPB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Per bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
sc_time MemSpec::getRefreshIntervalSB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Same bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,9 @@ public:
|
||||
|
||||
virtual ~MemSpec() {}
|
||||
|
||||
virtual sc_time getRefreshIntervalAB() const = 0;
|
||||
virtual sc_time getRefreshIntervalPB() const = 0;
|
||||
virtual sc_time getRefreshIntervalAB() const;
|
||||
virtual sc_time getRefreshIntervalPB() const;
|
||||
virtual sc_time getRefreshIntervalSB() const;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const = 0;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0;
|
||||
|
||||
@@ -95,12 +95,6 @@ sc_time MemSpecDDR3::getRefreshIntervalAB() const
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecDDR3::getRefreshIntervalPB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecDDR3", "Per bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time MemSpecDDR3::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
|
||||
@@ -88,7 +88,6 @@ public:
|
||||
const double iDD3P1;
|
||||
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
|
||||
@@ -114,12 +114,6 @@ sc_time MemSpecDDR4::getRefreshIntervalAB() const
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecDDR4::getRefreshIntervalPB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecDDR4", "Per bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time MemSpecDDR4::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
|
||||
@@ -95,7 +95,6 @@ public:
|
||||
const double iDD62;
|
||||
const double vDD2;
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
|
||||
@@ -91,6 +91,7 @@ MemSpecDDR5::MemSpecDDR5(json &memspec)
|
||||
tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")),
|
||||
tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")),
|
||||
tREFI (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")),
|
||||
tREFIsb (tCK * parseUint(memspec["memtimingspec"]["REFISB"], "REFISB")),
|
||||
tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")),
|
||||
tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")),
|
||||
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")),
|
||||
@@ -113,10 +114,9 @@ sc_time MemSpecDDR5::getRefreshIntervalAB() const
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecDDR5::getRefreshIntervalPB() const
|
||||
sc_time MemSpecDDR5::getRefreshIntervalSB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecDDR5", "Per bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
return tREFIsb;
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
|
||||
@@ -85,6 +85,7 @@ public:
|
||||
const sc_time tRFCsb_slr;
|
||||
const sc_time tRFCsb_dlr;
|
||||
const sc_time tREFI;
|
||||
const sc_time tREFIsb;
|
||||
const sc_time tREFSBRD_slr;
|
||||
const sc_time tREFSBRD_dlr;
|
||||
const sc_time tRTRS;
|
||||
@@ -99,8 +100,8 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalSB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
|
||||
@@ -85,8 +85,8 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
|
||||
@@ -85,8 +85,8 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
|
||||
@@ -87,8 +87,8 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
|
||||
@@ -80,8 +80,8 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
|
||||
@@ -80,8 +80,8 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
|
||||
@@ -101,12 +101,6 @@ sc_time MemSpecWideIO::getRefreshIntervalAB() const
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecWideIO::getRefreshIntervalPB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecWideIO", "Per bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time MemSpecWideIO::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
|
||||
@@ -93,7 +93,6 @@ public:
|
||||
const double iDD62;
|
||||
const double vDD2;
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
|
||||
@@ -74,8 +74,8 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
|
||||
@@ -57,7 +57,7 @@ void BankMachine::updateState(Command command)
|
||||
currentState = BmState::Activated;
|
||||
currentRow = DramExtension::getRow(currentPayload);
|
||||
break;
|
||||
case Command::PRE: case Command::PREA:
|
||||
case Command::PRE: case Command::PREA: case Command::PRESB:
|
||||
currentState = BmState::Precharged;
|
||||
break;
|
||||
case Command::RD: case Command::WR:
|
||||
@@ -70,7 +70,7 @@ void BankMachine::updateState(Command command)
|
||||
case Command::PDEA: case Command::PDEP: case Command::SREFEN:
|
||||
sleeping = true;
|
||||
break;
|
||||
case Command::REFA: case Command::REFB:
|
||||
case Command::REFA: case Command::REFB: case Command::REFSB:
|
||||
sleeping = false;
|
||||
blocked = false;
|
||||
break;
|
||||
|
||||
@@ -54,9 +54,10 @@
|
||||
#include "cmdmux/CmdMuxOldest.h"
|
||||
#include "respqueue/RespQueueFifo.h"
|
||||
#include "respqueue/RespQueueReorder.h"
|
||||
#include "refresh/RefreshManagerRankwise.h"
|
||||
#include "refresh/RefreshManagerDummy.h"
|
||||
#include "refresh/RefreshManagerRankwise.h"
|
||||
#include "refresh/RefreshManagerBankwise.h"
|
||||
#include "refresh/RefreshManagerGroupwise.h"
|
||||
#include "powerdown/PowerDownManagerStaggered.h"
|
||||
#include "powerdown/PowerDownManagerDummy.h"
|
||||
|
||||
@@ -185,6 +186,15 @@ Controller::Controller(sc_module_name name) :
|
||||
refreshManagers.push_back(manager);
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == "Groupwise")
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
RefreshManagerIF *manager = new RefreshManagerGroupwise
|
||||
(bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker);
|
||||
refreshManagers.push_back(manager);
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == "Bankwise")
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
@@ -271,28 +281,36 @@ void Controller::controllerMethod()
|
||||
if (!readyCommands.empty())
|
||||
{
|
||||
commandTuple = cmdMux->selectCommand(readyCommands);
|
||||
if (std::get<0>(commandTuple) != Command::NOP) // can happen with FIFO strict
|
||||
Command selectedCommand = std::get<0>(commandTuple);
|
||||
if (selectedCommand != Command::NOP) // can happen with FIFO strict
|
||||
{
|
||||
Rank rank = DramExtension::getRank(std::get<1>(commandTuple));
|
||||
BankGroup bankgroup = DramExtension::getBankGroup(std::get<1>(commandTuple));
|
||||
Bank bank = DramExtension::getBank(std::get<1>(commandTuple));
|
||||
tlm_generic_payload *selectedPayload = std::get<1>(commandTuple);
|
||||
Rank rank = DramExtension::getRank(selectedPayload);
|
||||
BankGroup bankgroup = DramExtension::getBankGroup(selectedPayload);
|
||||
Bank bank = DramExtension::getBank(selectedPayload);
|
||||
|
||||
if (isRankCommand(std::get<0>(commandTuple)))
|
||||
if (isRankCommand(selectedCommand))
|
||||
{
|
||||
for (auto it : bankMachinesOnRank[rank.ID()])
|
||||
it->updateState(std::get<0>(commandTuple));
|
||||
it->updateState(selectedCommand);
|
||||
}
|
||||
else if (isGroupCommand(selectedCommand))
|
||||
{
|
||||
for (unsigned bankID = (bank.ID() % memSpec->banksPerGroup);
|
||||
bankID < memSpec->banksPerRank; bankID += memSpec->banksPerGroup)
|
||||
bankMachinesOnRank[rank.ID()][bankID]->updateState(selectedCommand);
|
||||
}
|
||||
else
|
||||
bankMachines[bank.ID()]->updateState(std::get<0>(commandTuple));
|
||||
bankMachines[bank.ID()]->updateState(selectedCommand);
|
||||
|
||||
refreshManagers[rank.ID()]->updateState(std::get<0>(commandTuple));
|
||||
powerDownManagers[rank.ID()]->updateState(std::get<0>(commandTuple));
|
||||
checker->insert(std::get<0>(commandTuple), rank, bankgroup, bank);
|
||||
refreshManagers[rank.ID()]->updateState(selectedCommand);
|
||||
powerDownManagers[rank.ID()]->updateState(selectedCommand);
|
||||
checker->insert(selectedCommand, rank, bankgroup, bank);
|
||||
|
||||
if (isCasCommand(std::get<0>(commandTuple)))
|
||||
if (isCasCommand(selectedCommand))
|
||||
{
|
||||
scheduler->removeRequest(std::get<1>(commandTuple));
|
||||
respQueue->insertPayload(std::get<1>(commandTuple), memSpec->getIntervalOnDataStrobe(std::get<0>(commandTuple)).end);
|
||||
scheduler->removeRequest(selectedPayload);
|
||||
respQueue->insertPayload(selectedPayload, memSpec->getIntervalOnDataStrobe(selectedCommand).end);
|
||||
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
@@ -303,7 +321,7 @@ void Controller::controllerMethod()
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerEntry();
|
||||
|
||||
sendToDram(std::get<0>(commandTuple), std::get<1>(commandTuple));
|
||||
sendToDram(selectedCommand, selectedPayload);
|
||||
}
|
||||
else
|
||||
readyCmdBlocked = true;
|
||||
|
||||
@@ -53,6 +53,9 @@ CheckerDDR5::CheckerDDR5()
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
lastScheduledByCommandAndBankInGroup = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks * memSpec->banksPerGroup));
|
||||
|
||||
last4ActivatesLogical = std::vector<std::queue<sc_time>>(memSpec->numberOfLogicalRanks);
|
||||
last4ActivatesPhysical = std::vector<std::queue<sc_time>>(memSpec->numberOfPhysicalRanks);
|
||||
|
||||
@@ -80,6 +83,8 @@ CheckerDDR5::CheckerDDR5()
|
||||
tRDPDEN = memSpec->tRL + tRD_BURST + memSpec->tCK;
|
||||
tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK;
|
||||
tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK;
|
||||
|
||||
// TODO: tRTP BL 32!!! (check LPDDR4)
|
||||
}
|
||||
|
||||
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
@@ -91,6 +96,8 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank);
|
||||
Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank);
|
||||
|
||||
unsigned bankInGroupID = rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup;
|
||||
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
@@ -304,9 +311,37 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - memSpec->tCK);
|
||||
|
||||
// TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT?
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - memSpec->tCK);
|
||||
|
||||
// TODO: No tRFCsb_dlr between REFSB and ACT?
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - memSpec->tCK);
|
||||
|
||||
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front()
|
||||
+ memSpec->tFAW_slr - memSpec->tCK);
|
||||
|
||||
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front()
|
||||
+ memSpec->tFAW_dlr - memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
@@ -329,6 +364,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRESB][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -359,6 +398,40 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
// PRESB tPPD
|
||||
}
|
||||
else if (command == Command::PRESB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
// PREA tRP
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRESB][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -393,6 +466,67 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
|
||||
|
||||
// REFSB tRFCsb
|
||||
// PRESB tRP
|
||||
}
|
||||
else if (command == Command::REFSB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
// PREA tRP
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroupID];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
|
||||
|
||||
// TODO: check this
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
|
||||
|
||||
// TODO: check this
|
||||
lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_dlr);
|
||||
|
||||
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart,
|
||||
last4ActivatesLogical[logicalrank.ID()].front() + memSpec->tFAW_slr);
|
||||
|
||||
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart,
|
||||
last4ActivatesPhysical[physicalrank.ID()].front() + memSpec->tFAW_dlr);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerDDR5", "Unknown command!");
|
||||
@@ -420,7 +554,10 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b
|
||||
|
||||
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
|
||||
|
||||
if (command == Command::ACT)
|
||||
lastScheduledByCommandAndBankInGroup[command][rank.ID() * memSpec->banksPerGroup
|
||||
+ bank.ID() % memSpec->banksPerGroup] = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT || command == Command::REFSB)
|
||||
{
|
||||
if (last4ActivatesLogical[logicalrank.ID()].size() == 4)
|
||||
last4ActivatesLogical[logicalrank.ID()].pop();
|
||||
|
||||
@@ -59,6 +59,8 @@ private:
|
||||
std::vector<sc_time> lastScheduledByCommand;
|
||||
sc_time lastCommandOnBus;
|
||||
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankInGroup;
|
||||
|
||||
std::vector<std::queue<sc_time>> last4ActivatesPhysical;
|
||||
std::vector<std::queue<sc_time>> last4ActivatesLogical;
|
||||
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachines,
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachinesOnRank,
|
||||
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
|
||||
: bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
: bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
@@ -50,8 +50,9 @@ RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankM
|
||||
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->banksPerRank);
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++)
|
||||
{
|
||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachines[bankID]->getBankGroup(), bankMachines[bankID]->getBank());
|
||||
allBankMachines.push_back(bankMachines[bankID]);
|
||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[bankID]->getBankGroup(),
|
||||
bankMachinesOnRank[bankID]->getBank());
|
||||
allBankMachines.push_back(bankMachinesOnRank[bankID]);
|
||||
}
|
||||
remainingBankMachines = allBankMachines;
|
||||
currentBankMachine = *remainingBankMachines.begin();
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "RefreshManagerGroupwise.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/utils.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerGroupwise::RefreshManagerGroupwise(std::vector<BankMachine *> &bankMachines,
|
||||
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
|
||||
: bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
timeForNextTrigger = memSpec->getRefreshIntervalPB();
|
||||
|
||||
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->banksPerRank);
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++)
|
||||
{
|
||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachines[bankID]->getBankGroup(), bankMachines[bankID]->getBank());
|
||||
allBankMachines.push_back(bankMachines[bankID]);
|
||||
}
|
||||
remainingBankMachines = allBankMachines;
|
||||
currentBankMachine = *remainingBankMachines.begin();
|
||||
|
||||
maxPostponed = config.refreshMaxPostponed * memSpec->banksPerRank;
|
||||
maxPulledin = -(config.refreshMaxPulledin * memSpec->banksPerRank);
|
||||
}
|
||||
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time> RefreshManagerGroupwise::getNextCommand()
|
||||
{
|
||||
return std::tuple<Command, tlm_generic_payload *, sc_time>
|
||||
(nextCommand, &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->banksPerRank], timeToSchedule);
|
||||
}
|
||||
|
||||
sc_time RefreshManagerGroupwise::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
nextCommand = Command::NOP;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger)
|
||||
{
|
||||
powerDownManager->triggerInterruption();
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalPB())
|
||||
{
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
state = RmState::Regular;
|
||||
}
|
||||
|
||||
if (state == RmState::Regular)
|
||||
{
|
||||
bool forcedRefresh = (flexibilityCounter == maxPostponed);
|
||||
bool allBanksBusy = true;
|
||||
|
||||
if (!skipSelection)
|
||||
{
|
||||
currentIterator = remainingBankMachines.begin();
|
||||
currentBankMachine = *remainingBankMachines.begin();
|
||||
|
||||
for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++)
|
||||
{
|
||||
if ((*it)->isIdle())
|
||||
{
|
||||
currentIterator = it;
|
||||
currentBankMachine = *it;
|
||||
allBanksBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allBanksBusy && !forcedRefresh)
|
||||
{
|
||||
flexibilityCounter++;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentBankMachine->getState() == BmState::Activated)
|
||||
nextCommand = Command::PRE;
|
||||
else
|
||||
{
|
||||
nextCommand = Command::REFB;
|
||||
|
||||
if (forcedRefresh)
|
||||
{
|
||||
currentBankMachine->block();
|
||||
skipSelection = true;
|
||||
}
|
||||
}
|
||||
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
currentBankMachine->getBankGroup(), currentBankMachine->getBank());
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
else // if (state == RmState::Pulledin)
|
||||
{
|
||||
bool allBanksBusy = true;
|
||||
|
||||
for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++)
|
||||
{
|
||||
if ((*it)->isIdle())
|
||||
{
|
||||
currentIterator = it;
|
||||
currentBankMachine = *it;
|
||||
allBanksBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allBanksBusy)
|
||||
{
|
||||
state = RmState::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentBankMachine->getState() == BmState::Activated)
|
||||
nextCommand = Command::PRE;
|
||||
else
|
||||
nextCommand = Command::REFB;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
currentBankMachine->getBankGroup(), currentBankMachine->getBank());
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
|
||||
void RefreshManagerGroupwise::updateState(Command command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case Command::REFB:
|
||||
skipSelection = false;
|
||||
remainingBankMachines.erase(currentIterator);
|
||||
if (remainingBankMachines.empty())
|
||||
remainingBankMachines = allBankMachines;
|
||||
|
||||
if (state == RmState::Pulledin)
|
||||
flexibilityCounter--;
|
||||
else
|
||||
state = RmState::Pulledin;
|
||||
|
||||
if (flexibilityCounter == maxPulledin)
|
||||
{
|
||||
state = RmState::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
}
|
||||
break;
|
||||
case Command::REFA:
|
||||
// Refresh command after SREFEX
|
||||
state = RmState::Regular; // TODO: check if this assignment is necessary
|
||||
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalPB();
|
||||
sleeping = false;
|
||||
break;
|
||||
case Command::PDEA: case Command::PDEP:
|
||||
sleeping = true;
|
||||
break;
|
||||
case Command::SREFEN:
|
||||
sleeping = true;
|
||||
timeForNextTrigger = sc_max_time();
|
||||
break;
|
||||
case Command::PDXA: case Command::PDXP:
|
||||
sleeping = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef REFRESHMANAGERGROUPWISE_H
|
||||
#define REFRESHMANAGERGROUPWISE_H
|
||||
|
||||
#include "RefreshManagerIF.h"
|
||||
#include "../../configuration/memspec/MemSpec.h"
|
||||
#include "../BankMachine.h"
|
||||
#include "../powerdown/PowerDownManagerIF.h"
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <list>
|
||||
|
||||
class RefreshManagerGroupwise final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerGroupwise(std::vector<BankMachine *> &, PowerDownManagerIF *, Rank, CheckerIF *);
|
||||
|
||||
virtual std::tuple<Command, tlm::tlm_generic_payload *, sc_time> getNextCommand() override;
|
||||
virtual sc_time start() override;
|
||||
virtual void updateState(Command) override;
|
||||
|
||||
private:
|
||||
enum class RmState {Regular, Pulledin} state = RmState::Regular;
|
||||
const MemSpec *memSpec;
|
||||
std::vector<BankMachine *> &bankMachinesOnRank;
|
||||
PowerDownManagerIF *powerDownManager;
|
||||
std::vector<tlm::tlm_generic_payload> refreshPayloads;
|
||||
sc_time timeForNextTrigger = sc_max_time();
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
Rank rank;
|
||||
CheckerIF *checker;
|
||||
Command nextCommand = Command::NOP;
|
||||
|
||||
std::list<BankMachine *> remainingBankMachines;
|
||||
std::list<BankMachine *> allBankMachines;
|
||||
std::list<BankMachine *>::iterator currentIterator;
|
||||
BankMachine *currentBankMachine;
|
||||
|
||||
int flexibilityCounter = 0;
|
||||
int maxPostponed = 0;
|
||||
int maxPulledin = 0;
|
||||
|
||||
bool sleeping = false;
|
||||
bool skipSelection = false;
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGERGROUPWISE_H
|
||||
@@ -39,9 +39,9 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerRankwise::RefreshManagerRankwise(std::vector<BankMachine *> &bankMachines,
|
||||
RefreshManagerRankwise::RefreshManagerRankwise(std::vector<BankMachine *> &bankMachinesOnRank,
|
||||
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
|
||||
: bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
: bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
|
||||
Reference in New Issue
Block a user