Pullin test, ref alignment, several improvements
This commit is contained in:
@@ -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"/>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user