Refresh modes 1X, 2X and 4X - tRFC

This commit is contained in:
Éder F. Zulian
2018-07-03 11:24:06 +02:00
parent a787b7bb5b
commit 0ace967a67
18 changed files with 104 additions and 52 deletions

View File

@@ -9,10 +9,10 @@
<BankwiseLogic value="0"/>
<!-- Refresh yes, no -->
<ControllerCoreDisableRefresh value="0"/>
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (s.a.: DDR4) -->
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
<ControllerCoreRefMode value="1"/>
<!-- RGR -->
<ControllerCoreRowGranularRef value="1"/>
<ControllerCoreRowGranularRef value="0"/>
<ControllerCoreRowGranularRefNumAR value="8192"/>
<ControllerCoreRowGranularRefRowInc value="1"/>
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
@@ -40,7 +40,7 @@
<ControllerCoreRowGranularRefRCBInClkCycles value="37"/>
<ControllerCoreRowGranularRefFAWBInClkCycles value="0"/>
<!-- Postpone, pull-in -->
<ControllerCoreEnableRefPostpone value="1"/>
<ControllerCoreEnableRefPostpone value="0"/>
<ControllerCoreEnableRefPullIn value="0"/>
<ControllerCoreMaxPostponedARCmd value="8"/>
<ControllerCoreMaxPulledInARCmd value="8"/>

View File

@@ -1,9 +1,10 @@
<!DOCTYPE memspec SYSTEM "memspec.dtd">
<memspec>
<parameter id="memoryId" type="string" value="rgrspec" />
<parameter id="memoryType" type="string" value="DDR3" />
<parameter id="memoryType" type="string" value="DDR4" />
<memarchitecturespec>
<parameter id="width" type="uint" value="16" />
<parameter id="nbrOfBankGroups" type="uint" value="1" />
<parameter id="nbrOfBanks" type="uint" value="8" />
<parameter id="nbrOfRanks" type="uint" value="1" />
<parameter id="nbrOfColumns" type="uint" value="1024" />
@@ -25,18 +26,18 @@
<parameter id="RL" type="uint" value="18" />
<parameter id="RP" type="uint" value="18" />
<parameter id="RFC" type="uint" value="673" />
<parameter id="RFC2" type="uint" value="420" />
<parameter id="RFC4" type="uint" value="312" />
<parameter id="RAS" type="uint" value="34" />
<parameter id="WL" type="uint" value="12" />
<parameter id="AL" type="uint" value="0" />
<parameter id="DQSCK" type="uint" value="0" />
<parameter id="RTP" type="uint" value="6" />
<parameter id="WR" type="uint" value="15" />
<!-- doesn't matter (exit self-refresh) -->
<parameter id="XP" type="uint" value="4" />
<parameter id="XPDLL" type="uint" value="13" />
<parameter id="XS" type="uint" value="64" />
<parameter id="XSDLL" type="uint" value="512" />
<!-- -->
<parameter id="REFI" type="uint" value="9364" />
<parameter id="CL" type="uint" value="15" />
@@ -46,39 +47,30 @@
<parameter id="WTR" type="uint" value="8" />
<parameter id="CKE" type="uint" value="8" />
<parameter id="CKESR" type="uint" value="8" />
<parameter id="RRD_S" type="uint" value="4" />
<parameter id="RRD_L" type="uint" value="6" />
<parameter id="CCD_S" type="uint" value="4" />
<parameter id="CCD_L" type="uint" value="6" />
<parameter id="WTR_S" type="uint" value="3" />
<parameter id="WTR_L" type="uint" value="9" />
</memtimingspec>
<mempowerspec>
<parameter id="idd0" type="double" value="210.5" />
<!-- doesn't matter (power down) -->
<parameter id="idd2p0" type="double" value="16.0" />
<parameter id="idd2p1" type="double" value="55.0" />
<!-- -->
<parameter id="idd2n" type="double" value="99.0" />
<!-- doesn't matter (power down) -->
<parameter id="idd3p0" type="double" value="70.0" />
<parameter id="idd3p1" type="double" value="70.0" />
<!-- -->
<parameter id="idd3n" type="double" value="115.0" />
<parameter id="idd4w" type="double" value="1511.4" />
<parameter id="idd4r" type="double" value="1470.8" />
<parameter id="idd5" type="double" value="2000.0" />
<!-- doesn't matter (self-refresh) -->
<parameter id="idd6" type="double" value="22.0" />
<!-- -->
<parameter id="vdd" type="double" value="1.2" />
<!--
For the paper tests were made with memory type DDR3.
There was a problem with DDR3 memspec loading discussed in
https://git.rhrk.uni-kl.de/EIT-Wehn/dram.vp.system/issues/202
In summary, when loading DDR3 specs the values of vdd, idd0 and
idd6 were assigned to vdd2, idd02 and idd62 (second voltage
domain).
The specs provided for testing considered only one voltage
domain. It was required to treat the DDR3 problem like a feature.
Since the problem was fixed this specs will not produce the same
behavior.
See also:
https://git.rhrk.uni-kl.de/EIT-Wehn/dram.vp.system/pull/203
-->
<parameter id="idd02" type="double" value="4.05" />
<parameter id="idd62" type="double" value="2.6" />
<parameter id="vdd2" type="double" value="2.5" />
</mempowerspec>
</memspec>

View File

@@ -70,7 +70,7 @@ std::string commandToString(Command command)
return "PRE_ALL";
break;
case Command::AutoRefresh:
return "AUTO_REFRESH";
return "REF";
break;
case Command::PDNA:

View File

@@ -90,8 +90,12 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload)
} else if (command == Command::PrechargeAll) {
return config.tRP;
} else if (command == Command::AutoRefresh) {
return getElementFromMap(config.refreshTimings,
DramExtension::getExtension(payload).getBank()).tRFC;
if (Configuration::getInstance().getRefMode() == 4)
return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC4;
else if (Configuration::getInstance().getRefMode() == 2)
return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC2;
else
return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC;
} else if (command == Command::PDNAX || command == Command::PDNPX
|| command == Command::SREFX) {
return config.clk;

View File

@@ -277,12 +277,16 @@ void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *memspec)
config.memSpec.tXSRDLL = clk * queryUIntParameter(timings, "XSDLL");
config.memSpec.tAL = clk * queryUIntParameter(timings, "AL");
config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC");
config.memSpec.tRFC2 = clk * queryUIntParameter(timings, "RFC2");
config.memSpec.tRFC4 = clk * queryUIntParameter(timings, "RFC4");
config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI");
config.memSpec.tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
config.memSpec.refreshTimings.clear();
for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) {
config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC,
config.memSpec.tRFC2,
config.memSpec.tRFC4,
config.memSpec.tREFI);
}

View File

@@ -44,8 +44,11 @@
struct RefreshTiming {
RefreshTiming() {}
RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tREFI(tREFI) {}
RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tRFC2(SC_ZERO_TIME), tRFC4(SC_ZERO_TIME), tREFI(tREFI) {}
RefreshTiming(sc_time tRFC, sc_time tRFC2, sc_time tRFC4, sc_time tREFI) : tRFC(tRFC), tRFC2(tRFC2), tRFC4(tRFC4), tREFI(tREFI) {}
sc_time tRFC;
sc_time tRFC2;
sc_time tRFC4;
sc_time tREFI;
};
@@ -109,7 +112,9 @@ struct MemSpec {
sc_time tAL; //additive delay (delayed execution in dram)
sc_time tDQSCK;
sc_time tRFC; //min ref->act delay
sc_time tRFC; //min ref->act delay 1X mode
sc_time tRFC2; //min ref->act delay 2X mode
sc_time tRFC4; //min ref->act delay 4X mode
sc_time tREFI; //auto refresh must be issued at an average periodic interval tREFI
// Currents and Voltages:

View File

@@ -52,6 +52,7 @@ RefreshManager::RefreshManager(sc_module_name /*name*/,
{
auto m = controllerCore.config.getRefMode();
tREFIx = timing.tREFI / m;
tRFCx = m == 4 ? timing.tRFC4 : m == 2 ? timing.tRFC2 : timing.tRFC;
if (controllerCore.config.ControllerCoreEnableRefPostpone) {
maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd * m;
}
@@ -163,7 +164,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload
doRefresh(payload, time);
arCmdCounter++;
nextState = ST_PULLIN;
nextRefTiming = timing.tRFC;
nextRefTiming = tRFCx;
} else {
alignValue = arCmdCounter; // Saving value to be used by ST_ALIGN
nextState = ST_ALIGN;
@@ -214,7 +215,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload
nextRefTiming = SC_ZERO_TIME;
} else {
nextState = ST_BURST;
nextRefTiming = timing.tRFC;
nextRefTiming = tRFCx;
}
break;
@@ -222,10 +223,10 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload
// Align Refresh. Adjusting the timing so the next REF timing will be a in a time multiple of tREFIx
if (previousState == ST_PULLIN) {
nextRefTiming = tREFIx - (timing.tRFC * (alignValue));
nextRefTiming = tREFIx - (tRFCx * (alignValue));
nextState = ST_SKIP;
} else {
nextRefTiming = tREFIx - (timing.tRFC * (alignValue - 1));
nextRefTiming = tREFIx - (tRFCx * (alignValue - 1));
nextState = ST_REFRESH;
}
break;

View File

@@ -60,6 +60,7 @@ private:
RefreshTiming &timing;
sc_time nextPlannedRefresh;
sc_time tREFIx;
sc_time tRFCx;
std::map<Bank, tlm::tlm_generic_payload> refreshPayloads;
unsigned int maxpostpone = 0;
unsigned int maxpullin = 0;

View File

@@ -47,6 +47,7 @@ RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name,
{
auto m = controllerCore.config.getRefMode();
tREFIx = timing.tREFI / m;
tRFCx = m == 4 ? timing.tRFC4 : m == 2 ? timing.tRFC2 : timing.tRFC;
if (controllerCore.config.ControllerCoreEnableRefPostpone)
maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd * m;
if (controllerCore.config.ControllerCoreEnableRefPullIn)
@@ -147,7 +148,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
doRefresh(payload, time);
arCmdCounter[bank]++;
nextState[bank] = ST_PULLIN;
nextRefTiming = timing.tRFC;
nextRefTiming = tRFCx;
} else {
alignValue[bank] = arCmdCounter[bank]; // Saving value to be used by ST_ALIGN
nextState[bank] = ST_ALIGN;
@@ -206,7 +207,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
nextRefTiming = SC_ZERO_TIME;
} else {
nextState[bank] = ST_BURST;
nextRefTiming = timing.tRFC;
nextRefTiming = tRFCx;
}
break;
@@ -215,10 +216,10 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
// a in a time multiple of tREFIx.
if (previousState[bank] == ST_PULLIN) {
nextRefTiming = tREFIx - (timing.tRFC * (alignValue[bank]));
nextRefTiming = tREFIx - (tRFCx * (alignValue[bank]));
nextState[bank] = ST_SKIP;
} else {
nextRefTiming = tREFIx - (timing.tRFC * (alignValue[bank] - 1));
nextRefTiming = tREFIx - (tRFCx * (alignValue[bank] - 1));
nextState[bank] = ST_REFRESH;
}
break;

View File

@@ -60,6 +60,7 @@ private:
ControllerCore &controllerCore;
RefreshTiming &timing;
sc_time tREFIx;
sc_time tRFCx;
std::map<Bank, tlm::tlm_generic_payload> refreshPayloads;
std::map<Bank, sc_time> nextPlannedRefreshs;
unsigned int maxpostpone = 0;

View File

@@ -62,8 +62,14 @@ void ActBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
config.memSpec.tRP);
} else if (lcb.getCommand() == Command::AutoRefresh) {
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC);
} else if (lcb.getCommand() == Command::PDNPX
auto m = Configuration::getInstance().getRefMode();
if (m == 4)
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC4);
else if (m == 2)
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC2);
else
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC);
} else if (lcb.getCommand() == Command::PDNPX
|| lcb.getCommand() == Command::PDNAX) {
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tXP);
} else if (lcb.getCommand() == Command::SREFX) {

View File

@@ -71,8 +71,13 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
config.memSpec.tRP);
} else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec.tRFC);
auto m = Configuration::getInstance().getRefMode();
if (m == 4)
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC4);
else if (m == 2)
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC2);
else
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC);
} else if (lastCommandOnBank.getCommand() == Command::PDNPX
|| lastCommandOnBank.getCommand() == Command::PDNAX) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),

View File

@@ -54,7 +54,13 @@ sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd,
constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
config.memSpec.clk;
} else if (lastCmd == Command::AutoRefresh) {
constraint = config.memSpec.tRFC;
auto m = Configuration::getInstance().getRefMode();
if (m == 4)
constraint = config.memSpec.tRFC4;
else if (m == 2)
constraint = config.memSpec.tRFC2;
else
constraint = config.memSpec.tRFC;
} else if (lastCmd == Command::PDNPX || lastCmd == Command::PDNAX) {
constraint = config.memSpec.tXP;
} else if (lastCmd == Command::SREFX) {

View File

@@ -70,10 +70,15 @@ const
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
config.memSpec.tRP);
} else if (lastCommand.getCommand() == Command::AutoRefresh) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec.tRFC);
} else if (lastCommand.getCommand() == Command::PDNAX
|| lastCommand.getCommand() == Command::PDNPX) {
auto m = Configuration::getInstance().getRefMode();
if (m == 4)
command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRFC4);
else if (m == 2)
command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRFC2);
else
command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRFC);
} else if (lastCommand.getCommand() == Command::PDNAX
|| lastCommand.getCommand() == Command::PDNPX) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec.tXP);
} else if (lastCommand.getCommand() == Command::SREFX) {

View File

@@ -151,7 +151,13 @@ struct Dram : sc_module {
memTimingSpec.RC = Configuration::getInstance().memSpec.tRC / clk;
memTimingSpec.RCD = Configuration::getInstance().memSpec.tRCD / clk;
memTimingSpec.REFI = Configuration::getInstance().memSpec.tREFI / clk;
memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC / clk;
auto m = Configuration::getInstance().getRefMode();
if (m == 4)
memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC4 / clk;
else if (m == 2)
memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC2 / clk;
else
memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC / clk;
memTimingSpec.RL = Configuration::getInstance().memSpec.tRL / clk;
memTimingSpec.RP = Configuration::getInstance().memSpec.tRP / clk;
memTimingSpec.RRD = Configuration::getInstance().memSpec.tRRD_S / clk;

View File

@@ -131,7 +131,7 @@ def memory_utilisation_percent_old(connection):
def refreshMissDecision(connection, calculatedMetrics):
cursor = connection.cursor()
cursor.execute("""SELECT phases.ID,PhaseBegin,PhaseEnd,TBank FROM Phases INNER JOIN transactions on transactions.id = phases.transact WHERE PhaseName='AUTO_REFRESH' """)
cursor.execute("""SELECT phases.ID,PhaseBegin,PhaseEnd,TBank FROM Phases INNER JOIN transactions on transactions.id = phases.transact WHERE PhaseName IN ('REFA')' """)
queryMinREQ = """SELECT id,min(PhaseBegin) FROM (SELECT transactions.id, PhaseBegin FROM transactions
inner join ranges on ranges.id = transactions.range inner join phases on phases.transact = transactions.id
where tthread != 0 and tbank = :bank and PhaseName = "REQ" and ranges.begin<:begin and ranges.end>:end)"""

View File

@@ -10,6 +10,7 @@ class DramConfig(object):
memoryType = ""
scheduler = ""
bankwiseLogic = 0
refMode = 1
clk = 0
unitOfTime = ""
dataRate = 0
@@ -38,7 +39,9 @@ class DramConfig(object):
tXSR = 0 # min delay to row access command after srefx
tXSRDLL = 0 # min delay to row access command after srefx for dll commands
tAL = 0 # additive delay (delayed execution in dram)
tRFC = 0 # min ref->act delay
tRFC = 0 # min ref->act delay 1X
tRFC2 = 0 # min ref->act delay 2X
tRFC4 = 0 # min ref->act delay 4X
tREFI = 0 # time between REF commands
def readConfigFromFiles(self, connection):
@@ -52,6 +55,7 @@ class DramConfig(object):
self.unitOfTime = clkWithUnit[1].lower()
self.bankwiseLogic = mcconfig.getValue("BankwiseLogic")
self.refMode = mcconfig.getValue("ControllerCoreRefMode")
self.scheduler = mcconfig.getValue("Scheduler")
self.numberOfBanks = memspec.getIntValue("nbrOfBanks")
@@ -111,6 +115,8 @@ class DramConfig(object):
self.tXSRDLL = self.clk * memspec.getIntValue("XSDLL")
self.tAL = self.clk * memspec.getIntValue("AL")
self.tRFC = self.clk * memspec.getIntValue("RFC")
self.tRFC2 = self.clk * memspec.getIntValue("RFC2")
self.tRFC4 = self.clk * memspec.getIntValue("RFC4")
self.tREFI = self.clk * memspec.getIntValue("REFI")
elif (self. memoryType == "DDR3"):
@@ -353,7 +359,12 @@ def timing_constraint(FirstPhase, SecondPhase):
return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR + dramconfig.clk
elif (FirstPhaseName == "REFA"):
return dramconfig.tRFC
if dramconfig.refMode == "4":
return dramconfig.tRFC4
elif dramconfig.refMode == "2":
return dramconfig.tRFC2
else:
return dramconfig.tRFC
elif (FirstPhaseName in ["PDNA", "PDNP"]):
# print("{0}".format(FirstPhaseName))

View File

@@ -766,6 +766,10 @@ Below, the sub-configurations are listed and explained.
- "0": normal operation (refreshes enabled)
- ControllerCoreRefMode (unsigned int)
- Refresh mode. 1: 1X, 2: 2X, 4: 4X. Refresh period is tREFI, tREFI/2, tREFI/4, respectively. Number of rows per refresh affected accordingly.
The default refresh mode is fixed 1X mode where Refresh commands should be issued with the normal rate, i.e., tREFI. The duration of each refresh command is the normal refresh cycle time tRFC.
In 2X mode Refresh commands are issued to the DRAM at the double frequency (tREFI/2).
In 4X mode Refresh commands are issued to the DRAM at the quadruple frequency (tREFI/4).
There is a tRFC value for each mode that comes from the memory specification.
- *ControllerCoreForceMaxRefBurst* (boolean)
- "1": always postpone, resulting in a ControllerCoreMaxPostponedARCmd burst
- "0": normal operation