Postpone Refresh Implementation

This commit is contained in:
Ana Mativi
2017-07-28 17:30:56 +02:00
parent 9132e632c5
commit a2d2bcb7ca
9 changed files with 143 additions and 9 deletions

View File

@@ -9,4 +9,7 @@
<PowerDownTimeout value="100" />
<!-- Error Modelling -->
<ControllerCoreDisableRefresh value="0"/>
<ControllerCoreForceMaxRefPostpone value="0"/>
<ControllerCoreEnableRefPostpone value="0"/>
<ControllerCoreMaxPostponedARCmd value="8"/>
</mcconfig>

View File

@@ -8,6 +8,7 @@ OTHER_FILES += resources/simulations/wideio-example.xml
OTHER_FILES += resources/simulations/wideio-ecc.xml
OTHER_FILES += resources/simulations/ddr3-ecc.xml
OTHER_FILES += resources/simulations/sms-example.xml
OTHER_FILES += resources/simulations/ddr3_postpone_test.xml
# Simulator Files
OTHER_FILES += resources/configs/simulator/wideio.xml
@@ -69,6 +70,7 @@ OTHER_FILES += resources/traces/sms_t1.stl
OTHER_FILES += resources/traces/sms_t2.stl
OTHER_FILES += resources/traces/sms_t3.stl
OTHER_FILES += resources/traces/sms_t4.stl
OTHER_FILES += resources/traces/ddr3_postpone_test.stl
# Memory Controller Configs
OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml

View File

@@ -0,0 +1,19 @@
<simulation>
<!-- Configuration for the DRAMSys Simulator -->
<simconfig src="ddr3.xml" />
<!-- Temperature Simulator Configuration -->
<thermalconfig src="config.xml" />
<!-- Memory Device Specification: Which Device is on the DDR3 DIMM -->
<memspec src="MICRON_1Gb_DDR3-1600_8bit_G.xml"></memspec>
<!-- Addressmapping Configuration of the Memory Controller -->
<addressmapping src="am_ddr3_8x1Gbx8_dimm_p1KB_brc.xml"></addressmapping>
<!-- Memory Controller Configuration: -->
<mcconfig src="fifoStrict.xml"/>
<!--
The following trace setup is only used in standalone mode.
In library mode e.g. in Platform Architect the trace setup is ignored.
-->
<tracesetup>
<device clkMhz="1000">ddr3_postpone_test.stl</device>
</tracesetup>
</simulation>

View File

@@ -202,6 +202,12 @@ void Configuration::setParameter(std::string name, std::string value)
}
else if (name == "ControllerCoreDisableRefresh")
ControllerCoreDisableRefresh = string2bool(value);
else if (name == "ControllerCoreForceMaxRefPostpone")
ControllerCoreForceMaxRefPostpone = string2bool(value);
else if (name == "ControllerCoreEnableRefPostpone")
ControllerCoreEnableRefPostpone = string2bool(value);
else if (name == "ControllerCoreMaxPostponedARCmd")
ControllerCoreMaxPostponedARCmd = string2int(value);
else if (name == "ThermalSimulation")
ThermalSimulation = string2bool(value);
else if(name == "SimulationProgressBar")

View File

@@ -83,6 +83,9 @@ struct Configuration
bool Debug = false;
unsigned int NumberOfMemChannels = 1;
bool ControllerCoreDisableRefresh = false;
bool ControllerCoreForceMaxRefPostpone = false;
bool ControllerCoreEnableRefPostpone = false;
unsigned int ControllerCoreMaxPostponedARCmd = 8;
bool ThermalSimulation = false;
bool SimulationProgressBar = false;
unsigned int NumberOfDevicesOnDIMM = 1;

View File

@@ -46,11 +46,15 @@ using namespace tlm;
RefreshManager::RefreshManager(sc_module_name /*name*/, ControllerCore& controller) :
controllerCore(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME)
{
if (controllerCore.config.ControllerCoreEnableRefPostpone)
{
maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd;
}
for (Bank bank : controller.getBanks())
{
setUpDummy(refreshPayloads[bank], bank);
}
planNextRefresh();
planNextRefresh(timing.tREFI);
}
RefreshManager::~RefreshManager()
@@ -63,8 +67,7 @@ bool RefreshManager::hasCollision(const ScheduledCommand& command)
return command.getStart() < controllerCore.state->getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() >= nextPlannedRefresh;
}
//Schedule and trigger the refresh and plan the next one. AutoRefresh and PrechargeAll are scheduled just once per refresh period.
void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time)
void RefreshManager::doRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time)
{
sc_assert(!isInvalidated(payload, time));
@@ -99,20 +102,96 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribu
controllerCore.state->change(refreshAllMaster);
DramExtension::getExtension(refreshPayloads[Bank(0)]).incrementRow();
controllerCore.controller.send(refreshAllMaster, refreshPayloads[Bank(0)]);
planNextRefresh();
}
void RefreshManager::planNextRefresh()
bool RefreshManager::pendingRequests()
{
nextPlannedRefresh += timing.tREFI;
for (Bank bank : controllerCore.getBanks())
{
if (controllerCore.numberOfPayloads[bank] != 0)
return true;
}
return false;
}
//This function is sensitive to state transitions only. For multiple calls of this function we ensure that burst is only updated on a state change
void RefreshManager::evaluateBurstState()
{
bool pendingReq = pendingRequests();
if ((arCmdCounter == maxpostpone) || ((!pendingReq&&!burst) && !controllerCore.config.ControllerCoreForceMaxRefPostpone))
{
burst = true;
if (arCmdCounter>1) //A single refresh is considered a special case of a burst. It's only necessary to align if the burst consists of more than 1 AR command
{
alignToTrefiNeeded=true;
alignToTrefiValue=arCmdCounter-1; //For a burst consisting of multiple AR the gaps between the start of the burst and the last AR must be subtracted in order to align the next burst to tREFI
}
}
if (arCmdCounter == 0) //Burst is done. All AR commands are issued already
{
burst = false;
}
}
sc_time RefreshManager::alignToTrefi()
{
if (alignToTrefiNeeded) //Alignment is only needed when the previous burst consisted of more than 1 AR command
{
alignToTrefiNeeded = false; //This happens only for the first AR of the burst that follows
return alignToTrefiValue*timing.tRFC;
}
else
{
return SC_ZERO_TIME;
}
}
sc_time RefreshManager::getNextRefTiming()
{
if (burst)
{
return timing.tRFC;
}
else
{
return timing.tREFI-alignToTrefi();
}
}
//Depending on burst state, either schedule a refresh or postpone it. Check burst state before and after triggering a refresh to check if state changes are needed
void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time)
{
sc_time nextRefTiming;
if (!burst)
{
arCmdCounter++;
}
evaluateBurstState();
if (burst)
{
doRefresh(payload, time);
arCmdCounter--;
evaluateBurstState();
}
nextRefTiming = getNextRefTiming();
planNextRefresh(nextRefTiming);
}
void RefreshManager::planNextRefresh(sc_time nextRefTiming)
{
nextPlannedRefresh += nextRefTiming;
controllerCore.controller.send(REFTrigger, nextPlannedRefresh, refreshPayloads[Bank(0)]);
}
void RefreshManager::reInitialize(Bank /*bank*/, sc_time time)
{
nextPlannedRefresh = clkAlign(time, Alignment::DOWN);
planNextRefresh();
planNextRefresh(timing.tREFI);
}
bool RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time)

View File

@@ -59,9 +59,20 @@ private:
RefreshTiming& timing;
sc_time nextPlannedRefresh;
std::map<Bank, tlm::tlm_generic_payload> refreshPayloads;
unsigned int maxpostpone = 1;
unsigned int alignToTrefiValue = 0;
unsigned int arCmdCounter = 0;
bool burst = false;
bool alignToTrefiNeeded = false;
void planNextRefresh();
void doRefresh(tlm::tlm_generic_payload& payload, sc_time time);
void planNextRefresh(sc_time time);
void printDebugMessage(std::string message);
bool pendingRequests();
void burstRefresh();
void evaluateBurstState();
sc_time getNextRefTiming();
sc_time alignToTrefi();
};
#endif /* REFRESHMANAGER_H_ */

View File

@@ -70,6 +70,7 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
}
else if (lastCommandOnBank.getCommand() == Command::AutoRefresh)
{
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC);
}
else
reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand()));
@@ -108,6 +109,7 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
}
else if (lastCommand.getCommand() == Command::AutoRefresh)
{
command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRFC);
}
else
reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommand.getCommand()));

View File

@@ -741,6 +741,15 @@ Below, the sub-configurations are listed and explained.
- *ControllerCoreDisableRefresh* (boolean)
- "1": disables refreshes
- "0": normal operation (refreshes enabled)
- *ControllerCoreForceMaxRefPostpone* (boolean)
- "1": force the value on ControllerCoreMaxPostponedARCmd always. Requires ControllerCoreEnableRefPostpone to be enabled
- "0": normal operation
- *ControllerCoreEnableRefPostpone* (boolean)
- "1": enables the postpone refresh feature
- "0": normal operation
- *ControllerCoreMaxPostponedARCmd* (unsigned int)
- Max AR commands to be postponed.
- **Trace Setups**
- *clkMhz* (unsigned int)