first ddr4 changes

This commit is contained in:
Janik Schlemminger
2014-04-09 13:56:24 +02:00
parent 339dfbbdbb
commit 3bbf81584c
12 changed files with 101 additions and 40 deletions

View File

@@ -32,7 +32,7 @@
<!--<parameter id="CL" type="uint" value="3" />-->
<parameter id="TAW" type="uint" value="10" />
<parameter id="RRD" type="uint" value="2" />
<!--<parameter id="CCD" type="uint" value="1" />-->
<parameter id="CCD" type="uint" value="1" />
<parameter id="WTR" type="uint" value="3" />
<parameter id="CKE" type="uint" value="3" />
<parameter id="CKESR" type="uint" value="3" />

View File

@@ -156,22 +156,6 @@ bool ControllerCore::isBusy(sc_time time, Bank bank)
}
BankGroup ControllerCore::getBankGroup(Bank bank) const
{
static std::map<Bank, BankGroup> bankgroups;
if (bankgroups.size() == 0)
{
SC_ASSERT_(config.NumberOfBanks % config.NumberOfBankGroups == 0, "Number of banks must be a multiple of number of bankgroups");
for (unsigned int bank = 0; bank < config.NumberOfBanks; bank++)
{
unsigned int group = bank / config.NumberOfBankGroups;
bankgroups.insert(std::pair<Bank, BankGroup>(Bank(bank), BankGroup(group)));
}
}
return bankgroups.at(bank);
}
const std::vector<Bank>& ControllerCore::getBanks() const
{
static std::vector<Bank> banks;

View File

@@ -37,8 +37,8 @@ public:
void saveState();
void resetState();
BankGroup getBankGroup(Bank bank) const;
const std::vector<Bank>& getBanks() const;
const std::vector<Bank>& getBanks() const;//TODO put in config?
void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const;
ICommandChecker& getCommandChecker(Command command);

View File

@@ -68,7 +68,7 @@ void ControllerState::change(const ScheduledCommand& scheduledCommand)
break;
case Command::Activate:
bankStates.openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow());
lastActivates.emplace(scheduledCommand.getStart());
lastActivates.emplace(scheduledCommand.getStart(), scheduledCommand.getBank());
break;
case Command::Precharge:

View File

@@ -44,7 +44,7 @@ public:
std::map<Command, std::map<Bank, ScheduledCommand> > lastCommandsOnBus;
Slots bus;
std::list<ScheduledCommand> lastDataStrobeCommands;
std::set<sc_time> lastActivates;
std::map<sc_time, Bank> lastActivates;
private:
Configuration* config;

View File

@@ -57,7 +57,50 @@ void MemSpecLoader::loadConfig(Configuration& config, XMLElement* memspec)
void MemSpecLoader::loadDDR4(Configuration& config, XMLElement* memspec)
{
//MemSpecification
XMLElement* architecture = memspec->FirstChildElement("memarchitecturespec");
config.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
config.NumberOfBankGroups = queryUIntParameter(architecture, "nbrOfBankGroups");
config.BurstLength = queryUIntParameter(architecture, "burstLength");
config.nActivate = 4;
config.DataRate = queryUIntParameter(architecture, "dataRate");
config.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
//MemTimings
XMLElement* timings = memspec->FirstChildElement("memtimingspec");
double clkMhz = queryDoubleParameter(timings, "clkMhz");
sc_time clk = sc_time(1 / clkMhz, SC_US);
config.Timings.clk = clk;
//TODO
config.Timings.tRP = clk * queryUIntParameter(timings, "RP");
config.Timings.tRAS = clk * queryUIntParameter(timings, "RAS");
config.Timings.tRC = clk * queryUIntParameter(timings, "RC");
config.Timings.tRRD_S = clk * queryUIntParameter(timings, "RRD_S");
config.Timings.tRRD_L = clk * queryUIntParameter(timings, "RRD_L");
config.Timings.tCCD_S = clk * queryUIntParameter(timings, "CCD_S");
config.Timings.tCCD_L = clk * queryUIntParameter(timings, "CCD_L");
config.Timings.tRCD = clk * queryUIntParameter(timings, "RCD");
config.Timings.tNAW = clk * queryUIntParameter(timings, "TAW");
config.Timings.tRL = clk * queryUIntParameter(timings, "RL");
config.Timings.tWL = clk * queryUIntParameter(timings, "WL");
config.Timings.tWR = clk * queryUIntParameter(timings, "WR");
config.Timings.tWTR_S = clk * queryUIntParameter(timings, "WTR_S");
config.Timings.tWTR_L = clk * queryUIntParameter(timings, "WTR_L");
config.Timings.tCKESR = clk * queryUIntParameter(timings, "CKESR");
config.Timings.tCKE = clk * queryUIntParameter(timings, "CKE");
config.Timings.tXP = clk * queryUIntParameter(timings, "XP");
config.Timings.tXSR = clk * queryUIntParameter(timings, "XS");
config.Timings.tAL = clk * queryUIntParameter(timings, "AL");
config.Timings.tRFC = clk * queryUIntParameter(timings, "RFC");
config.Timings.tREFI = clk * queryUIntParameter(timings, "REFI");
config.Timings.refreshTimings.clear();
for (unsigned int i = 0; i < config.NumberOfBanks; ++i)
{
config.Timings.refreshTimings.push_back(
RefreshTiming(config.Timings.tRFC, config.Timings.tREFI));
}
}
void MemSpecLoader::loadWideIO(Configuration& config, XMLElement* memspec)
@@ -81,13 +124,17 @@ void MemSpecLoader::loadWideIO(Configuration& config, XMLElement* memspec)
config.Timings.tRP = clk * queryUIntParameter(timings, "RP");
config.Timings.tRAS = clk * queryUIntParameter(timings, "RAS");
config.Timings.tRC = clk * queryUIntParameter(timings, "RC");
config.Timings.tRRD = clk * queryUIntParameter(timings, "RRD");
config.Timings.tRRD_S = clk * queryUIntParameter(timings, "RRD");
config.Timings.tRRD_L = config.Timings.tRRD_S;
config.Timings.tCCD_S = clk * queryUIntParameter(timings, "CCD");
config.Timings.tCCD_L = config.Timings.tCCD_S;
config.Timings.tRCD = clk * queryUIntParameter(timings, "RCD");
config.Timings.tNAW = clk * queryUIntParameter(timings, "TAW");
config.Timings.tRL = clk * queryUIntParameter(timings, "RL");
config.Timings.tWL = clk * queryUIntParameter(timings, "WL");
config.Timings.tWR = clk * queryUIntParameter(timings, "WR");
config.Timings.tWTR = clk * queryUIntParameter(timings, "WTR");
config.Timings.tWTR_S = clk * queryUIntParameter(timings, "WTR");
config.Timings.tWTR_L = config.Timings.tWTR_S;
config.Timings.tCKESR = clk * queryUIntParameter(timings, "CKESR");
config.Timings.tCKE = clk * queryUIntParameter(timings, "CKE");
config.Timings.tXP = clk * queryUIntParameter(timings, "XP");

View File

@@ -30,17 +30,17 @@ struct TimingConfiguration
sc_time tRP; //precharge-time (pre -> act same bank)
sc_time tRAS; //active-time (act -> pre same bank)
sc_time tRC; //RAS-cycle-time (min time bw 2 succesive ACT to same bank)
sc_time tCCD; //TODO: relevant? max(bl, tCCD)
//sc_time tCCD_L;
sc_time tRRD; //min time bw 2 succesive ACT to different banks (different bank group)
//sc_time tRRD_L; //.. (same bank group)
sc_time tCCD_S; //TODO: relevant? max(bl, tCCD)
sc_time tCCD_L;
sc_time tRRD_S; //min time bw 2 succesive ACT to different banks (different bank group)
sc_time tRRD_L; //.. (same bank group)
sc_time tRCD; //act -> read/write
sc_time tNAW; //n activate window
sc_time tRL; //read latency (read command start to data strobe)
sc_time tWL; //write latency
sc_time tWR; //write recovery (write to precharge)
sc_time tWTR; //write to read (different bank group)
//sc_time tWTR_L; //.. (same bank group)
sc_time tWTR_S; //write to read (different bank group)
sc_time tWTR_L; //.. (same bank group)
sc_time tCKESR; //min time in sref
sc_time tCKE; //min time in pdna or pdnp
sc_time tXP; //min delay to row access command after pdnpx pdnax
@@ -54,7 +54,7 @@ struct TimingConfiguration
//act and read/write commands remain for this timespan in history
sc_time tActHistory(){return tNAW;}
sc_time tDataStrobeHistory(){return tWTR;}
sc_time tDataStrobeHistory(){return tWTR_L;}
};
} /* namespace core */

View File

@@ -33,7 +33,7 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXP);
}
else if(lastCommandOnBank.getCommand() == Command::SREFX)
else if (lastCommandOnBank.getCommand() == Command::SREFX)
{
command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXSR);
}
@@ -72,11 +72,16 @@ void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank(ScheduledComm
bool ActivateChecker::satsfies_activateToActivate_differentBank(ScheduledCommand& command) const
{
for (sc_time time : state.lastActivates)
for (auto act : state.lastActivates)
{
if ((time < command.getStart() && command.getStart() - time < config.Timings.tRRD)
|| (command.getStart() <= time && time - command.getStart() < config.Timings.tRRD))
return false;
sc_time time = act.first;
sc_time tRRD =
(getBankGroup(command.getBank()) == getBankGroup(act.second)) ?
config.Timings.tRRD_L : config.Timings.tRRD_S;
if ((time < command.getStart() && command.getStart() - time < tRRD)
|| (command.getStart() <= time && time - command.getStart() < tRRD))
return false;
}
return true;
}
@@ -90,15 +95,15 @@ bool ActivateChecker::satisfies_nActivateWindow(ScheduledCommand& command) const
*/
if (state.lastActivates.size() >= config.nActivate)
{
set<sc_time> lastActivates = state.lastActivates;
lastActivates.emplace(command.getStart());
map<sc_time, Bank> lastActivates = state.lastActivates;
lastActivates.emplace(command.getStart(), command.getBank());
auto upper = lastActivates.begin();
advance(upper, config.nActivate);
auto lower = lastActivates.begin();
while (upper != lastActivates.end())
{
if (*upper - *lower < config.Timings.tNAW)
if (upper->first - lower->first < config.Timings.tNAW)
return false;
++upper;
++lower;

View File

@@ -85,7 +85,11 @@ bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read,
//write to read
else
{
return !(read.getStart()>= getIntervalOnDataStrobe(strobeCommand).end + config.Timings.tWTR);
sc_time tWTR =
(getBankGroup(read.getBank()) == getBankGroup(strobeCommand.getBank())) ?
config.Timings.tWTR_L : config.Timings.tWTR_S;
return !(read.getStart()>= getIntervalOnDataStrobe(strobeCommand).end + tWTR);
}
}
else

View File

@@ -82,8 +82,12 @@ bool WriteChecker::collidesWithStrobeCommand(ScheduledCommand& write,
//write to read
if (strobeCommand.getStart() >= write.getStart())
{
sc_time tWTR =
(getBankGroup(write.getBank()) == getBankGroup(strobeCommand.getBank())) ?
config.Timings.tWTR_L : config.Timings.tWTR_S;
return !(strobeCommand.getStart()
>= getIntervalOnDataStrobe(write).end + config.Timings.tWTR);
>= getIntervalOnDataStrobe(write).end + tWTR);
}
//read to write

View File

@@ -70,4 +70,20 @@ bool TimeInterval::intersects(TimeInterval other)
return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start);
}
BankGroup getBankGroup(Bank bank)
{
static std::map<Bank, BankGroup> bankgroups;
if (bankgroups.size() == 0)
{
SC_ASSERT_(config.NumberOfBanks % config.NumberOfBankGroups == 0, "Number of banks must be a multiple of number of bankgroups");
for (unsigned int bank = 0; bank < Configuration::getInstance().NumberOfBanks; bank++)
{
unsigned int group = bank / Configuration::getInstance().NumberOfBankGroups;
bankgroups.insert(std::pair<Bank, BankGroup>(Bank(bank), BankGroup(group)));
}
}
return bankgroups.at(bank);
}
}

View File

@@ -34,6 +34,7 @@ enum Alignment {UP, DOWN};
const sc_time clkAlign(sc_time time, sc_time clk, Alignment alignment = UP);
bool isClkAligned(sc_time time, sc_time clk);
BankGroup getBankGroup(Bank bank);
};
#endif /* UTILS_H_ */