diff --git a/dram/.cproject b/dram/.cproject index 86b45aea..5edbf2e0 100644 --- a/dram/.cproject +++ b/dram/.cproject @@ -19,7 +19,7 @@ - + @@ -61,8 +61,8 @@ - - + + @@ -96,24 +96,24 @@ + - - - - + + + - + diff --git a/dram/.settings/language.settings.xml b/dram/.settings/language.settings.xml index 127cd8ac..278289a3 100644 --- a/dram/.settings/language.settings.xml +++ b/dram/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + diff --git a/dram/resources/configs/memspecs/MatzesWideIO.xml b/dram/resources/configs/memspecs/MatzesWideIO.xml index 32e27ce1..79ff68ba 100644 --- a/dram/resources/configs/memspecs/MatzesWideIO.xml +++ b/dram/resources/configs/memspecs/MatzesWideIO.xml @@ -26,7 +26,7 @@ - + diff --git a/dram/resources/scripts/metrics.py b/dram/resources/scripts/metrics.py index f5be0fbf..4055effc 100644 --- a/dram/resources/scripts/metrics.py +++ b/dram/resources/scripts/metrics.py @@ -73,34 +73,31 @@ def timeInPowerStates(connection): cursor.execute("SELECT SUM(PhaseEnd-PhaseBegin) from Phases where PhaseName = 'PDNA'") timeInPDNA = cursor.fetchone() - if(timeInPDNA != None): - totalTimeInPDNA = timeInPDNA[0] - else: - totalTimeInPDNA = 0 + totalTimeInPDNA = timeInPDNA[0] + if(totalTimeInPDNA == None): + totalTimeInPDNA = 0.0 fractionInPDNA = totalTimeInPDNA*1.0/totalTimeAllBanks result.append(("Time in PDNA (%)", fractionInPDNA*100)) print("{0} {1}".format(result[-1][0],result[-1][1])) cursor.execute("SELECT SUM(PhaseEnd-PhaseBegin) from Phases where PhaseName = 'PDNP'") timeInPDNP = cursor.fetchone() - if(timeInPDNP != None): - totalTimeInPDNP = timeInPDNP[0] - else: - totalTimeInPDNP = 0 + totalTimeInPDNP = timeInPDNP[0] + if(totalTimeInPDNP == None): + totalTimeInPDNP = 0.0 fractionInPDNP = totalTimeInPDNP*1.0/totalTimeAllBanks result.append(("Time in PDNP (%)", fractionInPDNP*100)) print("{0} {1}".format(result[-1][0],result[-1][1])) cursor.execute("SELECT SUM(PhaseEnd-PhaseBegin) from Phases where PhaseName = 'SREF'") timeInSREF = cursor.fetchone() - if(timeInSREF != None): - totalTimeInSREF = timeInSREF[0] - else: - totalTimeInSREF = 0 + totalTimeInSREF = timeInSREF[0] + if(totalTimeInSREF == None): + totalTimeInSREF = 0.0 fractionInSREF = totalTimeInSREF*1.0/totalTimeAllBanks result.append(("Time in SREF (%)", fractionInSREF*100)) print("{0} {1}".format(result[-1][0],result[-1][1])) - result.insert(0,("Active time (%)", 1-fractionInPDNA-fractionInPDNP-fractionInSREF)) + result.insert(0,("Active time (%)", (1-fractionInPDNA-fractionInPDNP-fractionInSREF)*100)) print("{0} {1}".format(result[0][0],result[0][1])) return result diff --git a/dram/resources/scripts/tests.py b/dram/resources/scripts/tests.py index e0f15613..71ecbf5e 100644 --- a/dram/resources/scripts/tests.py +++ b/dram/resources/scripts/tests.py @@ -146,7 +146,9 @@ def row_buffer_is_used_correctly(connection): cursor.execute(query,{"bank": bankNumber}) rowBufferIsClosed = True + #phases that precharge the bank prechargingPhases = set(['PRE','PRE_ALL','RDA','WRA']) + #phases that require the bank to be precharged accessingPhases = set(['RD,RDA,WR,WRA,SREF,AUTO_REFRESH']) for currentRow in cursor: diff --git a/dram/src/common/TlmRecorder.cpp b/dram/src/common/TlmRecorder.cpp index 8a8c8738..2cd6fa4f 100644 --- a/dram/src/common/TlmRecorder.cpp +++ b/dram/src/common/TlmRecorder.cpp @@ -3,6 +3,7 @@ #include "dramExtension.h" #include "xmlAddressdecoder.h" #include "Utils.h" +#include "../core/configuration/Configuration.h" #include using namespace std; @@ -130,8 +131,8 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_int(insertGeneralInfoStatement, 3, xmlAddressDecoder::getInstance().getNumberOfBanks()); sqlite3_bind_text(insertGeneralInfoStatement, 4, "", 0, NULL); - sqlite3_bind_int(insertGeneralInfoStatement, 5, 6); - sqlite3_bind_text(insertGeneralInfoStatement, 6, "NS", 2, NULL); + sqlite3_bind_int(insertGeneralInfoStatement, 5, core::Configuration::getInstance().Timings.clk.value()); + sqlite3_bind_text(insertGeneralInfoStatement, 6, "PS", 2, NULL); executeSqlStatement(insertGeneralInfoStatement); } void TlmRecorder::insertTransactionInDB(unsigned int id, tlm::tlm_generic_payload& trans) diff --git a/dram/src/core/ControllerCore.cpp b/dram/src/core/ControllerCore.cpp index 0a5b2b81..a5961cb3 100644 --- a/dram/src/core/ControllerCore.cpp +++ b/dram/src/core/ControllerCore.cpp @@ -33,7 +33,9 @@ ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map 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_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 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 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_S; //write to read (different bank group) - sc_time tWTR_L; //.. (same bank group) + sc_time tWTR; //write to read (different bank group) + //sc_time tWTR; //.. (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 diff --git a/dram/src/core/powerdown/PowerDownManager.cpp b/dram/src/core/powerdown/PowerDownManager.cpp index e772ae48..963049d7 100644 --- a/dram/src/core/powerdown/PowerDownManager.cpp +++ b/dram/src/core/powerdown/PowerDownManager.cpp @@ -210,7 +210,7 @@ void PowerDownManager::sendPowerDownPayload(sc_time time, Bank bank, Command cmd time = clkAlign(time, controller.config.Timings.clk); //TODO is clkaligned already? tlm_generic_payload& payload = getPayload(bank); - ScheduledCommand pdn(cmd, time, SC_ZERO_TIME, DramExtension::getExtension(payload)); + ScheduledCommand pdn(cmd, time, controller.config.Timings.clk, DramExtension::getExtension(payload)); controller.state.bus.moveCommandToNextFreeSlot(pdn); controller.state.change(pdn); controller.wrapper.send(pdn, payload); diff --git a/dram/src/core/powerdown/PowerDownManagerGrouped.cpp b/dram/src/core/powerdown/PowerDownManagerGrouped.cpp index dba2806a..5ea04c53 100644 --- a/dram/src/core/powerdown/PowerDownManagerGrouped.cpp +++ b/dram/src/core/powerdown/PowerDownManagerGrouped.cpp @@ -116,14 +116,14 @@ void PowerDownManagerGrouped::sendPowerDownPayload(sc_time time, Command cmd) //just to find slot tlm_generic_payload& payload = getPayload(Bank(0)); - ScheduledCommand pdn(cmd, time, SC_ZERO_TIME, DramExtension::getExtension(payload)); + ScheduledCommand pdn(cmd, time, controller.config.Timings.clk, DramExtension::getExtension(payload)); controller.state.bus.moveCommandToNextFreeSlot(pdn); for (Bank bank : controller.getBanks()) { tlm_generic_payload& payloadToSend = getPayload(bank); - ScheduledCommand pdnToSend(cmd, pdn.getStart(), SC_ZERO_TIME, DramExtension::getExtension(payloadToSend)); + ScheduledCommand pdnToSend(cmd, pdn.getStart(), controller.config.Timings.clk, DramExtension::getExtension(payloadToSend)); controller.state.change(pdnToSend); controller.wrapper.send(pdnToSend, payloadToSend); } diff --git a/dram/src/core/scheduling/CommandSequenceGenerator.cpp b/dram/src/core/scheduling/CommandSequenceGenerator.cpp index b01aaa81..3bd228e8 100644 --- a/dram/src/core/scheduling/CommandSequenceGenerator.cpp +++ b/dram/src/core/scheduling/CommandSequenceGenerator.cpp @@ -7,6 +7,7 @@ #include "CommandSequenceGenerator.h" #include "../../common/dramExtension.h" +#include "../configuration/Configuration.h" using namespace std; @@ -66,14 +67,20 @@ CommandSequence CommandSequenceGenerator::getRowHitCommandSequence(tlm::tlm_gene Command CommandSequenceGenerator::getReadWriteCommand(tlm::tlm_generic_payload& transaction) { + if (transaction.get_command() == tlm::TLM_READ_COMMAND) { - //TODO READA - return Command::Read; + if(Configuration::getInstance().OpenPagePolicy) + return Command::Read; + else + return Command::ReadA; } else { - return Command::Write; + if(Configuration::getInstance().OpenPagePolicy) + return Command::Write; + else + return Command::WriteA; } } diff --git a/dram/src/core/scheduling/ScheduledCommand.cpp b/dram/src/core/scheduling/ScheduledCommand.cpp index 81c451d8..a2d15a06 100644 --- a/dram/src/core/scheduling/ScheduledCommand.cpp +++ b/dram/src/core/scheduling/ScheduledCommand.cpp @@ -67,7 +67,7 @@ Row ScheduledCommand::getRow() const return extension.getRow(); } -unsigned int ScheduledCommand::getBurstLength() +unsigned int ScheduledCommand::getBurstLength() const { return extension.getBurstlength(); } diff --git a/dram/src/core/scheduling/ScheduledCommand.h b/dram/src/core/scheduling/ScheduledCommand.h index 87bf162c..b4e9876e 100644 --- a/dram/src/core/scheduling/ScheduledCommand.h +++ b/dram/src/core/scheduling/ScheduledCommand.h @@ -47,7 +47,7 @@ public: Bank getBank() const; Row getRow() const; - unsigned int getBurstLength(); + unsigned int getBurstLength() const; bool operator ==(const ScheduledCommand& b) const; bool commandIsIn(const std::vector& commandSet) const; diff --git a/dram/src/core/scheduling/checker/ActivateChecker.cpp b/dram/src/core/scheduling/checker/ActivateChecker.cpp index 20fa468a..9b287bdd 100644 --- a/dram/src/core/scheduling/checker/ActivateChecker.cpp +++ b/dram/src/core/scheduling/checker/ActivateChecker.cpp @@ -23,27 +23,32 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const if (lastCommandOnBank.isValidCommand()) { - if (isIn(lastCommandOnBank.getCommand(), { Command::Precharge, Command::PrechargeAll, - Command::AutoRefresh, Command::ReadA, Command::WriteA })) + if (isIn(lastCommandOnBank.getCommand(), { Command::Precharge, Command::AutoRefresh, + Command::ReadA, Command::WriteA })) { - if (command.getStart() < lastCommandOnBank.getEnd()) - { - command.setStart(lastCommandOnBank.getEnd()); - } + command.delayToMeetConstraint(lastCommandOnBank.getEnd(), SC_ZERO_TIME); } - else if (lastCommandOnBank.getCommand() == Command::SREFX ||lastCommandOnBank.getCommand() == Command::PDNPX||lastCommandOnBank.getCommand() == Command::PDNAX) + else if (lastCommandOnBank.getCommand() == Command::PDNPX + || lastCommandOnBank.getCommand() == Command::PDNAX) { - + command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXP); + } + else if(lastCommandOnBank.getCommand() == Command::SREFX) + { + command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXSR); } else - reportFatal("Activate Checker", "Activate can not follow " + commandToString(lastCommandOnBank.getCommand())); + reportFatal("Activate Checker", + "Activate can not follow " + commandToString(lastCommandOnBank.getCommand())); } delay_to_satisfy_activateToActivate_sameBank(command); - while (!(state.bus.isFree(command.getStart()) && satsfies_activateToActivate_differentBank(command) && satisfies_nActivateWindow(command))) + while (!(state.bus.isFree(command.getStart()) + && satsfies_activateToActivate_differentBank(command) + && satisfies_nActivateWindow(command))) { - command.delayStart(config.Timings.clk); + command.delayStart(config.Timings.clk); } } @@ -67,19 +72,18 @@ void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank(ScheduledComm bool ActivateChecker::satsfies_activateToActivate_differentBank(ScheduledCommand& command) const { - for(sc_time time : state.lastActivates) + for (sc_time time : state.lastActivates) { - if((time < command.getStart() && command.getStart()-time= config.nActivate) + if (state.lastActivates.size() >= config.nActivate) { set lastActivates = state.lastActivates; lastActivates.emplace(command.getStart()); @@ -87,9 +91,9 @@ bool ActivateChecker::satisfies_nActivateWindow(ScheduledCommand& command) const advance(upper, config.nActivate); auto lower = lastActivates.begin(); - while(upper != lastActivates.end()) + while (upper != lastActivates.end()) { - if(*upper-*lower < config.Timings.tNAW) + if (*upper - *lower < config.Timings.tNAW) return false; ++upper; ++lower; diff --git a/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp b/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp index 673986bb..39cf5e97 100644 --- a/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp +++ b/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp @@ -28,13 +28,17 @@ void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand& command) c { command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tWR); } - else if (lastCommand.commandIsIn( { Command::PDNAX, Command::PDNPX, Command::SREFX, + else if(lastCommand.getCommand() == Command::WriteA) + { + command.delayToMeetConstraint(lastCommand.getEnd(), SC_ZERO_TIME); + if(config.Timings.tWR > config.Timings.tRP) + command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tWR - config.Timings.tRP); + } + else if (lastCommand.commandIsIn( {Command::ReadA, Command::PDNAX, Command::PDNPX, Command::SREFX, Command::AutoRefresh })) { - if (command.getStart() < lastCommand.getEnd()) - { - command.setStart(lastCommand.getEnd()); - } + + command.delayToMeetConstraint(lastCommand.getEnd(), SC_ZERO_TIME); } else reportFatal("Precharge All Checker", diff --git a/dram/src/core/scheduling/checker/PrechargeChecker.cpp b/dram/src/core/scheduling/checker/PrechargeChecker.cpp index 13ffb7c9..315d2a3d 100644 --- a/dram/src/core/scheduling/checker/PrechargeChecker.cpp +++ b/dram/src/core/scheduling/checker/PrechargeChecker.cpp @@ -31,7 +31,7 @@ void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons } else if (lastCommand.getCommand() == Command::PDNAX) { - + command.delayToMeetConstraint(lastCommand.getEnd(), SC_ZERO_TIME); } else reportFatal("Precharge Checker", diff --git a/dram/src/core/scheduling/checker/ReadChecker.cpp b/dram/src/core/scheduling/checker/ReadChecker.cpp index 2123a238..e2d9c605 100644 --- a/dram/src/core/scheduling/checker/ReadChecker.cpp +++ b/dram/src/core/scheduling/checker/ReadChecker.cpp @@ -21,18 +21,14 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { if (lastCommand.getCommand() == Command::Activate) { - if (command.getStart() < lastCommand.getEnd()) - { - command.setStart(lastCommand.getEnd()); - } + command.delayToMeetConstraint(lastCommand.getEnd(), SC_ZERO_TIME); } - else if (lastCommand.getCommand() == Command::Read - || lastCommand.getCommand() == Command::Write) + else if (lastCommand.getCommand() == Command::Read || lastCommand.getCommand() == Command::Write) { } else if (lastCommand.getCommand() == Command::PDNAX) { - + command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tXP); } else reportFatal("Read Checker", @@ -56,8 +52,7 @@ sc_time ReadChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, } else { - return config.Timings.tRL + config.Timings.clk * payload.get_streaming_width() - + config.Timings.tRP; + return config.Timings.clk * payload.get_streaming_width() + max(config.Timings.tRP,config.Timings.tRL); } } @@ -77,15 +72,7 @@ bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read, { if (strobeCommand.getCommand() == Command::Read || strobeCommand.getCommand() == Command::ReadA) { - //read to read - if(read.getStart() < strobeCommand.getStart()) - { - return (strobeCommand.getStart() - read.getStart() < read.getBurstLength()*config.Timings.clk); - } - else - { - return (read.getStart() - strobeCommand.getStart() < strobeCommand.getBurstLength()*config.Timings.clk); - } + return getIntervalOnDataStrobe(read).intersects(getIntervalOnDataStrobe(strobeCommand)); } else if (strobeCommand.getCommand() == Command::Write || strobeCommand.getCommand() == Command::WriteA) @@ -93,12 +80,12 @@ bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read, //read to write if (strobeCommand.getStart() >= read.getStart()) { - return !(strobeCommand.getStart() >= getIntervalOnDataStrobe(read, config.Timings).end); + return !(strobeCommand.getStart() >= getIntervalOnDataStrobe(read).end); } //write to read else { - return !(read.getStart()>= getIntervalOnDataStrobe(strobeCommand, config.Timings).end + config.Timings.tWTR); + return !(read.getStart()>= getIntervalOnDataStrobe(strobeCommand).end + config.Timings.tWTR); } } else diff --git a/dram/src/core/scheduling/checker/WriteChecker.cpp b/dram/src/core/scheduling/checker/WriteChecker.cpp index c048a385..05cb9c0a 100644 --- a/dram/src/core/scheduling/checker/WriteChecker.cpp +++ b/dram/src/core/scheduling/checker/WriteChecker.cpp @@ -21,15 +21,16 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { if (lastCommand.getCommand() == Command::Activate) { - if (command.getStart() < lastCommand.getEnd()) - { - command.setStart(lastCommand.getEnd()); - } + command.delayToMeetConstraint(lastCommand.getEnd(), SC_ZERO_TIME); } else if (lastCommand.getCommand() == Command::Read - || lastCommand.getCommand() == Command::Write - || lastCommand.getCommand() == Command::PDNAX) + || lastCommand.getCommand() == Command::Write) { + + } + else if (lastCommand.getCommand() == Command::PDNAX) + { + command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tXP); } else reportFatal("Write Checker", @@ -52,8 +53,7 @@ sc_time WriteChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, } else { - return config.Timings.tWL + config.Timings.clk * (payload.get_streaming_width() - 1) - + config.Timings.tRP; + return config.Timings.tWL + config.Timings.clk * payload.get_streaming_width() + config.Timings.tWR; } } @@ -74,17 +74,7 @@ bool WriteChecker::collidesWithStrobeCommand(ScheduledCommand& write, if (strobeCommand.getCommand() == Command::Write || strobeCommand.getCommand() == Command::WriteA) { - //write to write - if (write.getStart() < strobeCommand.getStart()) - { - return (strobeCommand.getStart() - write.getStart() - < write.getBurstLength() * config.Timings.clk); - } - else - { - return (write.getStart() - strobeCommand.getStart() - < strobeCommand.getBurstLength() * config.Timings.clk); - } + return getIntervalOnDataStrobe(write).intersects(getIntervalOnDataStrobe(strobeCommand)); } else if (strobeCommand.getCommand() == Command::Read || strobeCommand.getCommand() == Command::ReadA) @@ -93,13 +83,13 @@ bool WriteChecker::collidesWithStrobeCommand(ScheduledCommand& write, if (strobeCommand.getStart() >= write.getStart()) { return !(strobeCommand.getStart() - >= getIntervalOnDataStrobe(write, config.Timings).end + config.Timings.tWTR); + >= getIntervalOnDataStrobe(write).end + config.Timings.tWTR); } //read to write else { - return !(write.getStart() >= getIntervalOnDataStrobe(strobeCommand, config.Timings).end); + return !(write.getStart() >= getIntervalOnDataStrobe(strobeCommand).end); } } else diff --git a/dram/src/core/utils/Utils.cpp b/dram/src/core/utils/Utils.cpp index 05d7e887..d4a851b6 100644 --- a/dram/src/core/utils/Utils.cpp +++ b/dram/src/core/utils/Utils.cpp @@ -9,6 +9,7 @@ #include "../configuration/TimingConfiguration.h" #include "../ControllerCore.h" #include "../../common/DebugManager.h" +#include "../configuration/Configuration.h" namespace core { @@ -35,15 +36,22 @@ const sc_time clkAlign(sc_time time, sc_time clk, Alignment alignment) return floor(time / clk) * clk; } -TimeInterval getIntervalOnDataStrobe(const ScheduledCommand& command, const TimingConfiguration& config) +TimeInterval getIntervalOnDataStrobe(const ScheduledCommand& command) { sc_assert(command.getCommand() == Command::Read || command.getCommand() == Command::ReadA || command.getCommand() == Command::Write ||command.getCommand() == Command::WriteA); - if(command.getCommand() == Command::ReadA || command.getCommand() == Command::WriteA) - return TimeInterval(command.getStart(), command.getEnd() - config.tRP); + TimingConfiguration& timings = Configuration::getInstance().Timings; + + if(command.getCommand() == Command::Read || command.getCommand() == Command::ReadA) + { + return TimeInterval(command.getStart() + timings.tRL, command.getStart() + timings.tRL + timings.clk * command.getBurstLength()); + } else - return TimeInterval(command.getStart(),command.getEnd()); + { + //centered data strobe for write + return TimeInterval(command.getStart() + timings.tWL, command.getStart() + timings.tWL + timings.clk * (command.getBurstLength()-1)); + } } bool isClkAligned(sc_time time, sc_time clk) @@ -51,4 +59,15 @@ bool isClkAligned(sc_time time, sc_time clk) return !((time / clk) - ceil(time / clk)); } + +bool TimeInterval::timeIsInInterval(sc_time time) +{ + return (start < time && time < end); +} + +bool TimeInterval::intersects(TimeInterval other) +{ + return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start); +} + } diff --git a/dram/src/core/utils/Utils.h b/dram/src/core/utils/Utils.h index 3e2eb1d1..b979475e 100644 --- a/dram/src/core/utils/Utils.h +++ b/dram/src/core/utils/Utils.h @@ -21,19 +21,19 @@ struct TimeInterval { sc_time start,end; TimeInterval(sc_time start,sc_time end) : start(start), end(end){} - bool timeIsInInterval(sc_time time) - { - return (start<=time && time<=end); - } + + bool timeIsInInterval(sc_time time); + bool intersects(TimeInterval other); }; struct TimingConfiguration; sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint); -TimeInterval getIntervalOnDataStrobe(const ScheduledCommand& command, const TimingConfiguration& config); +TimeInterval getIntervalOnDataStrobe(const ScheduledCommand& command); 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); + }; #endif /* UTILS_H_ */ diff --git a/dram/src/scheduler/Fifo.cpp b/dram/src/scheduler/Fifo.cpp index 50822348..26c142f3 100644 --- a/dram/src/scheduler/Fifo.cpp +++ b/dram/src/scheduler/Fifo.cpp @@ -10,27 +10,27 @@ namespace scheduler { -bool scheduler::Fifo::hasTransactionForBank(Bank bank) +bool Fifo::hasTransactionForBank(Bank bank) { - return (!buffer.at(bank.ID()).empty()); + return !buffer[bank].empty(); } -void scheduler::Fifo::schedule(gp* payload) +void Fifo::schedule(gp* payload) { - buffer.at(DramExtension::getExtension(payload).getBank().ID()).push_back(payload); + buffer[DramExtension::getExtension(payload).getBank()].push_back(payload); } -gp* scheduler::Fifo::getTransactionForBank(Bank bank) +gp* Fifo::getTransactionForBank(Bank bank) { sc_assert(hasTransactionForBank(bank)); - gp* result = buffer.at(bank.ID()).front(); + gp* result = buffer[bank].front(); return result; } -void scheduler::Fifo::popTransactionForBank(Bank bank) +void Fifo::popTransactionForBank(Bank bank, gp* payload) { sc_assert(hasTransactionForBank(bank)); - buffer.at(bank.ID()).pop_front(); + buffer[bank].pop_front(); } } /* namespace scheduler */ diff --git a/dram/src/scheduler/Fifo.h b/dram/src/scheduler/Fifo.h index c8092cd6..94689c96 100644 --- a/dram/src/scheduler/Fifo.h +++ b/dram/src/scheduler/Fifo.h @@ -11,14 +11,15 @@ #include "Scheduler.h" #include "../core/ControllerCore.h" #include -#include +#include + namespace scheduler { class Fifo : public Scheduler { public: - Fifo(const core::ControllerCore& controller) : buffer(controller.getBanks().size()) + Fifo(const core::ControllerCore& controller) {} virtual ~Fifo() {} @@ -26,10 +27,10 @@ public: virtual bool hasTransactionForBank(Bank bank) override; virtual void schedule(gp* payload) override; virtual gp* getTransactionForBank(Bank bank) override; - virtual void popTransactionForBank(Bank bank) override; + virtual void popTransactionForBank(Bank bank, gp* payload) override; private: - std::vector> buffer; + std::map> buffer; }; } /* namespace scheduler */ diff --git a/dram/src/scheduler/Fr_Fcfs.cpp b/dram/src/scheduler/Fr_Fcfs.cpp index 1dc5dcaa..39af487b 100644 --- a/dram/src/scheduler/Fr_Fcfs.cpp +++ b/dram/src/scheduler/Fr_Fcfs.cpp @@ -1,50 +1,73 @@ #include "Fr_Fcfs.h" #include "../common/dramExtension.h" +#include "../core/configuration/Configuration.h" #include using namespace std; +using namespace core; namespace scheduler { -bool scheduler::FR_FCFS::hasTransactionForBank(Bank bank) + +bool FR_FCFS::hasTransactionForBank(Bank bank) { - return (buffer.at(bank.ID()).size() > 0); + return !buffer[bank].empty(); } -void scheduler::FR_FCFS::schedule(gp* payload) +void FR_FCFS::schedule(gp* payload) { - buffer.at(DramExtension::getExtension(payload).getBank().ID()).emplace_back(payload); + buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); } -gp* scheduler::FR_FCFS::getTransactionForBank(Bank bank) +gp* FR_FCFS::getTransactionForBank(Bank bank) { sc_assert(hasTransactionForBank(bank)); - list& payloads = buffer.at(bank.ID()); - auto found = - find_if(payloads.begin(), payloads.end(), - [&](gp* payload) - { return DramExtension::getExtension(payload).getRow() == bankstates.getRowInRowBuffer(bank);}); + auto rowHits = findRowHits(bank, bankstates.getRowInRowBuffer(bank)); + gp* result = rowHits.empty() ? buffer[bank].front() : rowHits.front(); + rowHits = findRowHits(bank, DramExtension::getExtension(result).getRow()); + + if (!core::Configuration::getInstance().AdaptiveOpenPagePolicy) + return result; - if (found != payloads.end()) - return *found; else - return payloads.front(); + { + if(rowHits.size() > 1) + Configuration::getInstance().OpenPagePolicy = true; + else + Configuration::getInstance().OpenPagePolicy = false; + + //other row hits are still in buffer, leave page open +// if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() > 1) +// Configuration::getInstance().OpenPagePolicy = true; +// else +// Configuration::getInstance().OpenPagePolicy = false; + + //no other hit in buffer, but row miss is waiting +// if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() == 1 && buffer[bank].size() > 2 ) +// Configuration::getInstance().OpenPagePolicy = false; +// else +// Configuration::getInstance().OpenPagePolicy = true; + + return result; + } } -void scheduler::FR_FCFS::popTransactionForBank(Bank bank) +std::vector FR_FCFS::findRowHits(Bank bank, Row row) +{ + vector found; + for (gp* payload : buffer[bank]) + { + if (DramExtension::getExtension(payload).getRow() == row) + found.push_back(payload); + } + return found; +} + +void FR_FCFS::popTransactionForBank(Bank bank, gp* payload) { sc_assert(hasTransactionForBank(bank)); - list& payloads = buffer.at(bank.ID()); - auto found = - find_if(payloads.begin(), payloads.end(), - [&](gp* payload) - { return DramExtension::getExtension(payload).getRow() == bankstates.getRowInRowBuffer(bank);}); - - if (found != payloads.end()) - payloads.erase(found); - else - payloads.erase(payloads.begin()); + buffer[bank].remove(payload); } } diff --git a/dram/src/scheduler/Fr_Fcfs.h b/dram/src/scheduler/Fr_Fcfs.h index f8f5f011..b6e25790 100644 --- a/dram/src/scheduler/Fr_Fcfs.h +++ b/dram/src/scheduler/Fr_Fcfs.h @@ -4,14 +4,14 @@ #include "Scheduler.h" #include "../core/ControllerCore.h" #include -#include +#include namespace scheduler { class FR_FCFS : public Scheduler { public: - FR_FCFS(core::ControllerCore& controller) : bankstates(controller.getBankStates()), buffer(controller.getBanks().size()) + FR_FCFS(core::ControllerCore& controller) : bankstates(controller.getBankStates()) {} virtual ~FR_FCFS() {} @@ -19,10 +19,11 @@ public: virtual bool hasTransactionForBank(Bank bank) override; virtual void schedule(gp* payload) override; virtual gp* getTransactionForBank(Bank bank) override; - virtual void popTransactionForBank(Bank bank) override; + virtual void popTransactionForBank(Bank bank, gp* payload) override; private: - std::vector> buffer; + std::vector findRowHits(Bank bank, Row row); + std::map> buffer; const core::BankStates& bankstates; }; diff --git a/dram/src/scheduler/Scheduler.h b/dram/src/scheduler/Scheduler.h index 54f3d386..931990c0 100644 --- a/dram/src/scheduler/Scheduler.h +++ b/dram/src/scheduler/Scheduler.h @@ -17,7 +17,7 @@ public: //TODO Rename to payload virtual bool hasTransactionForBank(Bank bank) = 0; virtual gp* getTransactionForBank(Bank bank) = 0; - virtual void popTransactionForBank(Bank bank) = 0; + virtual void popTransactionForBank(Bank bank, gp* payload) = 0; }; } diff --git a/dram/src/simulation/Controller.h b/dram/src/simulation/Controller.h index f7a2e056..41aa6536 100644 --- a/dram/src/simulation/Controller.h +++ b/dram/src/simulation/Controller.h @@ -50,7 +50,6 @@ public: inputBufferDelay = controller->config.Timings.clk; iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); - } ~Controller() @@ -77,10 +76,18 @@ public: dramPEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp()); dramPEQ.notify(payload, END_RD, command.getEnd() - sc_time_stamp()); break; + case Command::ReadA: + dramPEQ.notify(payload, BEGIN_RDA, command.getStart() - sc_time_stamp()); + dramPEQ.notify(payload, END_RDA, command.getEnd() - sc_time_stamp()); + break; case Command::Write: dramPEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp()); dramPEQ.notify(payload, END_WR, command.getEnd() - sc_time_stamp()); break; + case Command::WriteA: + dramPEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp()); + dramPEQ.notify(payload, END_WRA, command.getEnd() - sc_time_stamp()); + break; case Command::AutoRefresh: dramPEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp()); dramPEQ.notify(payload, END_AUTO_REFRESH, command.getEnd() - sc_time_stamp()); @@ -116,7 +123,7 @@ public: dramPEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp()); break; default: - SC_REPORT_FATAL(0, "unsupported command in controller wrapper"); + SC_REPORT_FATAL(0, "unsupported command in controller"); break; } @@ -155,8 +162,8 @@ private: void payloadEntersSystem(tlm_generic_payload& payload) { - printDebugMessage("Transaction enters system"); Bank bank = DramExtension::getExtension(payload).getBank(); + printDebugMessage("Transaction enters system on bank " + to_string(bank.ID())); numberOfPayloadsInSystem[bank] = numberOfPayloadsInSystem[bank] + 1; scheduler->schedule(&payload); } @@ -177,6 +184,12 @@ private: void scheduleNextPayload(Bank bank) { + if(bank.ID() == 5) + { + int i = 5; + ++i; + } + printDebugMessage("Triggering schedule next payload on bank " + to_string(bank.ID())); if (scheduler->hasTransactionForBank(bank)) { @@ -200,7 +213,7 @@ private: tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank); if (controller->scheduleRequest(sc_time_stamp(), *nextTransaction)) { - scheduler->popTransactionForBank(bank); + scheduler->popTransactionForBank(bank, nextTransaction); printDebugMessage("\t-> payload was scheduled by core"); } else @@ -266,13 +279,20 @@ private: scheduleNextPayload(bank); sendToDram(payload, phase, SC_ZERO_TIME); } - else if (phase == END_RD || phase == END_WR || phase == END_RDA || phase == END_WRA) + else if (phase == END_RD || phase == END_WR) { TlmRecorder::getInstance().recordPhase(payload, BEGIN_RESP, sc_time_stamp()); sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); payloadLeavesSystem(payload); } - else if (isIn(phase, { BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL })) + else if (phase == END_RDA || phase == END_WRA) + { + TlmRecorder::getInstance().recordPhase(payload, BEGIN_RESP, sc_time_stamp()); + sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + payloadLeavesSystem(payload); + scheduleNextPayload(bank); + } + else if (isIn(phase, { BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA,BEGIN_WRA })) { sendToDram(payload, phase, SC_ZERO_TIME); } diff --git a/dram/src/simulation/SimulationManager.cpp b/dram/src/simulation/SimulationManager.cpp index 038cefbd..06c32480 100644 --- a/dram/src/simulation/SimulationManager.cpp +++ b/dram/src/simulation/SimulationManager.cpp @@ -19,7 +19,7 @@ namespace simulation { SimulationManager::SimulationManager(sc_module_name name, std::string stl1, unsigned int burstlength1, std::string stl2, unsigned int burstlenght2, - std::string traceName, std::string pathToResources) : + std::string traceName, std::string pathToResources, bool silent) : dram("dram"), arbiter("arbiter"), controller("controller"), player1("player1", pathToResources + string("traces/") + stl1,burstlength1, this), player2("player2", pathToResources + string("traces/") + stl2,burstlenght2, this), traceName(traceName) @@ -37,13 +37,16 @@ SimulationManager::SimulationManager(sc_module_name name, std::string stl1, controller.iSocket.bind(dram.tSocket); vector whiteList; - whiteList.push_back(controller.name()); - whiteList.push_back(player2.name()); - whiteList.push_back(player1.name()); - whiteList.push_back(this->name()); - whiteList.push_back(TlmRecorder::senderName); - whiteList.push_back(ControllerCore::senderName); - whiteList.push_back(PowerDownManager::senderName); + if(!silent) + { + whiteList.push_back(controller.name()); + whiteList.push_back(player2.name()); + whiteList.push_back(player1.name()); + whiteList.push_back(this->name()); + whiteList.push_back(TlmRecorder::senderName); + whiteList.push_back(ControllerCore::senderName); + whiteList.push_back(PowerDownManager::senderName); + } DebugManager::getInstance().addToWhiteList(whiteList); } diff --git a/dram/src/simulation/SimulationManager.h b/dram/src/simulation/SimulationManager.h index 2a220ce8..ddfee8f2 100644 --- a/dram/src/simulation/SimulationManager.h +++ b/dram/src/simulation/SimulationManager.h @@ -24,7 +24,7 @@ public: SC_HAS_PROCESS(SimulationManager); SimulationManager(sc_module_name name, std::string stl1, unsigned int burstlength1, std::string stl2, unsigned int burstlenght2, - std::string traceName, std::string pathToResources); + std::string traceName, std::string pathToResources, bool silent=false); void startSimulation(); void tracePlayerFinishedCallback(string name) override; diff --git a/dram/src/simulation/main.cpp b/dram/src/simulation/main.cpp index 1a6eac07..2801180c 100644 --- a/dram/src/simulation/main.cpp +++ b/dram/src/simulation/main.cpp @@ -26,15 +26,15 @@ void startTraceAnalyzer(string traceName) int sc_main(int argc, char **argv) { - sc_set_time_resolution(1, SC_NS); + sc_set_time_resolution(1, SC_PS); string resources = pathOfFile(argv[0]) + string("/../resources/"); - string stl1 = "chstone-mips_32.stl"; + string stl1 = "chstone-sha_32.stl"; unsigned int burstlength1 = 4; string stl2 = "empty.stl"; unsigned int burstlength2 = 2; string traceName = "tpr.tdb"; - SimulationManager simulationManager("sim", stl1,burstlength1, stl2,burstlength2, traceName, resources); + SimulationManager simulationManager("sim", stl1,burstlength1, stl2,burstlength2, traceName, resources,false); simulationManager.startSimulation(); startTraceAnalyzer(traceName); return 0;