Pullin test, ref alignment, several improvements

This commit is contained in:
Éder F. Zulian
2018-07-09 17:09:39 +02:00
parent d4848de9e2
commit ebc0a0ef72
8 changed files with 98 additions and 95 deletions

View File

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

View File

@@ -15,7 +15,7 @@
<parameter id="nbrOfRows" type="uint" value="16384" />
<parameter id="nbrOfRows" type="uint" value="8192" />
-->
<parameter id="nbrOfRows" type="uint" value="131072" />
<parameter id="nbrOfRows" type="uint" value="8192" />
<parameter id="dataRate" type="uint" value="2" />
<parameter id="burstLength" type="uint" value="8" />
</memarchitecturespec>
@@ -40,14 +40,12 @@
<parameter id="XSDLL" type="uint" value="512" />
<parameter id="REFI" type="uint" value="9364" />
<parameter id="CL" type="uint" value="15" />
<parameter id="FAW" type="uint" value="37" />
<parameter id="RRD" type="uint" value="8" />
<parameter id="CCD" type="uint" value="4" />
<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" />
@@ -68,7 +66,6 @@
<parameter id="idd5" type="double" value="2000.0" />
<parameter id="idd6" type="double" value="22.0" />
<parameter id="vdd" type="double" value="1.2" />
<parameter id="idd02" type="double" value="4.05" />
<parameter id="idd62" type="double" value="2.6" />
<parameter id="vdd2" type="double" value="2.5" />

View File

@@ -14,10 +14,11 @@
<!-- <tracesetup id="no_refresh_fr_fcfs_nbw_b16_ddr4_8b_1x"> -->
<tracesetup id="rgrsetup">
<!--
<device clkMhz="1000">rgr_pullin_test.stl</device>
<device clkMhz="1000">rgr_postpone_test.stl</device>
<device clkMhz="1000">rgr_bw_postpone_test.stl</device>
<device clkMhz="1000">1_720x1280_64-Pixelgroesse_imb3_str1_scram_ddr4_8b_same_clock.stl</device>
-->
<device clkMhz="1000">rgr_postpone_test.stl</device>
<device clkMhz="1000">rgr_pullin_test.stl</device>
</tracesetup>
</simulation>

View File

@@ -32,6 +32,8 @@
* Author: Éder F. Zulian
*/
#include <math.h>
#include "RGR.h"
#include "../ControllerCore.h"
#include "../TimingCalculation.h"
@@ -42,14 +44,23 @@ using namespace std;
RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore),
timing(ctrlcore.config.memSpec.refreshTimings[ccore.getBanks()[0]])
{
fmb = ccore.config.ControllerCoreForceMaxRefBurst;
bwl = ccore.config.BankwiseLogic;
ri = ccore.config.getRowInc();
auto nr = ccore.config.memSpec.NumberOfRows;
auto nar = ccore.config.getNumAR();
auto m = ccore.config.getRefMode();
rpr = (nr / m) / nar;
assert(rpr > 0);
tREFIx = timing.tREFI / m;
if (ccore.config.ControllerCoreEnableRefPostpone)
maxpostpone = ccore.config.ControllerCoreMaxPostponedARCmd * m;
if (ccore.config.ControllerCoreEnableRefPullIn)
maxpullin = ccore.config.ControllerCoreMaxPulledInARCmd * m;
trp = ccore.config.getTrpb();
trcd = ccore.config.memSpec.tRCD;
postponeEnabled = ccore.config.ControllerCoreEnableRefPostpone;
pullInEnabled = ccore.config.ControllerCoreEnableRefPullIn;
maxpostpone = ccore.config.ControllerCoreMaxPostponedARCmd * m;
maxpullin = ccore.config.ControllerCoreMaxPulledInARCmd * m;
#if 0
if (ccore.config.BankwiseLogic) {
if (bwl) {
for (Bank b : ccore.getBanks()) {
auto nbs = ccore.config.memSpec.NumberOfBanks;
nextPlannedRefreshs[b] = b.ID() * tREFIx / nbs;
@@ -57,20 +68,20 @@ RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore),
}
#endif
for (Bank b : ccore.getBanks()) {
nextPlannedRefreshs[b] = SC_ZERO_TIME;
arCmdCounter[b] = 0;
alignValue[b] = 0;
pulledin[b] = 0;
postponed[b] = 0;
currentState[b] = ST_REFRESH;
previousState[b] = ST_REFRESH;
nextState[b] = ST_REFRESH;
setUpDummy(rps[b], b);
nextPlannedRefreshs[b] = SC_ZERO_TIME;
}
if (ccore.config.BankwiseLogic) {
for (Bank b : ccore.getBanks()) {
planNextRefresh(b, tREFIx);
planNextRefresh(b, tREFIx, false);
}
} else {
planNextRefresh(ccore.getBanks()[0], tREFIx);
planNextRefresh(ccore.getBanks()[0], tREFIx, false);
}
}
@@ -80,35 +91,17 @@ RGR::~RGR()
bool RGR::hasCollision(const ScheduledCommand __attribute__((unused)) &cmd)
{
#if 0
bool r = false;
nbs = ccore.config.memSpec.NumberOfBanks;
for (unsigned b = 0; b < nbs; b++) {
if (cmd.getStart() < currentRefresh[b] && cmd.getEnd() > currentRefresh[b])
r = true;
if (cmd.getStart() < nextPlannedRefreshs[b]
&& cmd.getEnd() > nextPlannedRefreshs[b])
r = true;
}
return r;
#else
return false;
#endif
}
void RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t)
sc_time RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t)
{
sc_assert(!isInvalidated(p, t));
auto nr = ccore.config.memSpec.NumberOfRows;
auto nar = ccore.config.getNumAR();
auto ri = ccore.config.getRowInc();
auto m = ccore.config.getRefMode();
assert(((nr / m) / nar) > 0);
Bank b = DramExtension::getExtension(p).getBank();
bool bwl = ccore.config.BankwiseLogic;
bool o = ccore.state->rowBufferStates->rowBufferIsOpen(b);
bool ac = ccore.state->rowBufferStates->allRowBuffersAreClosed();
bool pre = !!(bwl ? o : (!ac));
bool openBank = ccore.state->rowBufferStates->rowBufferIsOpen(b);
bool allClosed = ccore.state->rowBufferStates->allRowBuffersAreClosed();
bool pre = bwl ? openBank : !allClosed;
sc_time trfcx = SC_ZERO_TIME;
if (!bwl) {
for (Bank b : ccore.getBanks()) {
@@ -119,22 +112,24 @@ void RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t)
}
if (pre) {
if (!bwl) {
trfcx += trp;
if (bwl) {
if (ccore.config.getRGRBank(b.ID())) {
ccore.scheduleRequest(Command::PreB, rps[b]);
}
} else {
for (Bank b : ccore.getBanks()) {
auto rgrb = ccore.config.getRGRBank(b.ID());
if (ccore.state->rowBufferStates->rowBufferIsOpen(b) && rgrb) {
ccore.scheduleRequest(Command::PreB, rps[Bank(b)]);
}
}
} else {
if (ccore.config.getRGRBank(b.ID())) {
ccore.scheduleRequest(Command::PreB, rps[b]);
}
}
}
for (unsigned r = 0; r < ((nr / m) / nar); r += ri) {
if (!!bwl) {
for (unsigned r = 0; r < rpr; r += ri) {
trfcx += trcd + trp;
if (bwl) {
if (ccore.config.getRGRBank(b.ID())) {
ccore.scheduleRequest(Command::ActB, rps[b]);
ccore.scheduleRequest(Command::PreB, rps[b]);
@@ -150,28 +145,32 @@ void RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t)
}
}
}
return trfcx;
}
void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t)
{
sc_time nrt;
sc_time trfcx;
Bank b = DramExtension::getExtension(p).getBank();
auto bwl = ccore.config.BankwiseLogic;
bool preq = bwl ? ccore.hasPendingRequests(b) : ccore.hasPendingRequests();
bool canPostpone = preq && (arCmdCounter[b] < maxpostpone);
bool canPullIn = !preq && (arCmdCounter[b] < maxpullin);
bool fmb = !!ccore.config.ControllerCoreForceMaxRefBurst;
bool postpone = postponeEnabled && preq && (postponed[b] < maxpostpone);
bool pullIn = pullInEnabled && !preq && (pulledin[b] < maxpullin);
previousState[b] = currentState[b];
currentState[b] = nextState[b];
bool align = false;
switch (currentState[b]) {
case ST_REFRESH:
assert(arCmdCounter[b] == 0);
if (canPostpone) {
assert(pulledin[b] == 0 && postponed[b] == 0);
if (postpone) {
nrt = SC_ZERO_TIME;
nextState[b] = ST_POSTPONE;
nrt = SC_ZERO_TIME;
} else if (canPullIn) {
} else if (pullIn) {
trfcx = doRefresh(p, t);
nrt = trfcx;
nextState[b] = ST_PULLIN;
nrt = SC_ZERO_TIME;
} else {
doRefresh(p, t);
nrt = tREFIx;
@@ -179,70 +178,69 @@ void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t)
}
break;
case ST_PULLIN:
if (canPullIn) {
doRefresh(p, t);
arCmdCounter[b]++;
if (pullIn) {
trfcx = doRefresh(p, t);
pulledin[b]++;
nrt = trfcx;
nextState[b] = ST_PULLIN;
nrt = SC_ZERO_TIME;
} else {
alignValue[b] = arCmdCounter[b];
nextState[b] = ST_ALIGN;
nrt = SC_ZERO_TIME;
nextState[b] = ST_ALIGN;
}
break;
case ST_SKIP:
arCmdCounter[b]--;
if (arCmdCounter[b] == 0) {
nextState[b] = ST_REFRESH;
if (pulledin[b] == 0) {
nrt = SC_ZERO_TIME;
nextState[b] = ST_REFRESH;
} else {
nextState[b] = ST_SKIP;
pulledin[b]--;
nrt = tREFIx;
nextState[b] = ST_SKIP;
}
break;
case ST_POSTPONE:
if ((arCmdCounter[b] == maxpostpone) || ((!preq) && !fmb)) {
if (arCmdCounter[b] < maxpostpone) {
arCmdCounter[b]++;
}
alignValue[b] = arCmdCounter[b];
nextState[b] = ST_BURST;
postponed[b]++;
if ((postponed[b] > maxpostpone) || (!preq && !fmb)) {
// Burst triggered by inactivity or max postpone value reached.
nrt = SC_ZERO_TIME;
nextState[b] = ST_BURST;
} else {
arCmdCounter[b]++;
nextState[b] = ST_POSTPONE;
nrt = tREFIx;
nextState[b] = ST_POSTPONE;
}
break;
case ST_BURST:
arCmdCounter[b]--;
doRefresh(p, t);
if (arCmdCounter[b] == 0) {
postponed[b]--;
if (postponed[b] == 0) {
nrt = SC_ZERO_TIME;
nextState[b] = ST_ALIGN;
nrt = SC_ZERO_TIME;
} else {
nextState[b] = ST_BURST;
nrt = SC_ZERO_TIME;
nextState[b] = ST_BURST;
}
break;
case ST_ALIGN:
nrt = tREFIx;
align = true;
if (previousState[b] == ST_PULLIN) {
nrt = tREFIx;
nextState[b] = ST_SKIP;
} else {
nrt = tREFIx;
nextState[b] = ST_REFRESH;
}
break;
default:
SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop.");
SC_REPORT_FATAL(this->name(), "Invalid state in RGR flexible refresh FSM. Stop.");
break;
}
planNextRefresh(!bwl ? ccore.getBanks()[0] : b, nrt);
planNextRefresh(bwl ? b : ccore.getBanks()[0], nrt, align);
}
void RGR::planNextRefresh(Bank b, sc_time t)
void RGR::planNextRefresh(Bank b, sc_time t, bool align)
{
if (align) {
nextPlannedRefreshs[b] = trunc(nextPlannedRefreshs[b].to_double() / tREFIx.to_double()) * tREFIx;
}
nextPlannedRefreshs[b] += t;
ccore.controller.send(REFTrigger, nextPlannedRefreshs[b], rps[b]);
}
@@ -250,7 +248,7 @@ void RGR::planNextRefresh(Bank b, sc_time t)
void RGR::reInitialize(Bank b, sc_time t)
{
nextPlannedRefreshs[b] = clkAlign(t, Alignment::DOWN);
planNextRefresh(b, tREFIx);
planNextRefresh(b, tREFIx, true);
}
bool RGR::isInvalidated(tlm::tlm_generic_payload &p, sc_time t)

View File

@@ -43,27 +43,34 @@ class RGR : public IRefreshManager, public sc_module
public:
RGR(sc_module_name, ControllerCore &ctrlcore);
virtual ~RGR();
virtual bool hasCollision(const ScheduledCommand __attribute__((
unused)) &command) override;
virtual bool hasCollision(const ScheduledCommand &cmd) override;
virtual void scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) override;
void reInitialize(Bank bank, sc_time time) override;
bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) override;
private:
bool fmb;
bool bwl;
unsigned int ri;
unsigned int rpr;
sc_time trp;
sc_time trcd;
sc_time tREFIx;
ControllerCore &ccore;
RefreshTiming &timing;
std::map<Bank, tlm::tlm_generic_payload> rps;
std::map<Bank, sc_time> nextPlannedRefreshs;
std::map<Bank, sc_time> currentRefresh;
unsigned int maxpostpone = 0;
unsigned int maxpullin = 0;
std::map<Bank, unsigned int> arCmdCounter;
std::map<Bank, unsigned int> alignValue;
bool postponeEnabled;
bool pullInEnabled;
unsigned int maxpostpone;
unsigned int maxpullin;
std::map<Bank, unsigned int> pulledin;
std::map<Bank, unsigned int> postponed;
std::map<Bank, ref_fsm_state_t> currentState;
std::map<Bank, ref_fsm_state_t> previousState;
std::map<Bank, ref_fsm_state_t> nextState;
void doRefresh(tlm::tlm_generic_payload &p, sc_time t);
void planNextRefresh(Bank b, sc_time t);
sc_time doRefresh(tlm::tlm_generic_payload &p, sc_time t);
void planNextRefresh(Bank b, sc_time t, bool align);
void printDebugMessage(std::string message);
};
#endif /* RGR_MANAGER_H_ */

View File

@@ -231,7 +231,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload,
}
break;
default:
SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop.");
SC_REPORT_FATAL(this->name(), "Invalid state in flexible refresh FSM. Stop.");
break;
}
planNextRefresh(nextRefTiming);

View File

@@ -217,7 +217,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
}
break;
default:
SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop.");
SC_REPORT_FATAL(this->name(), "Invalid state in bankwise flexible refresh FSM. Stop.");
break;
}

View File

@@ -70,7 +70,7 @@ traceSetup::traceSetup(std::string uri,
std::string name = device->GetText();
int pos = name.rfind('.');
size_t pos = name.rfind('.');
if (pos == std::string::npos) {
throw std::runtime_error("Name of the trace file does not contain a valid extension.");
}