diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_256Mb_WIDEIO-200_128bit.xml b/DRAMSys/library/resources/configs/memspecs/JEDEC_256Mb_WIDEIO-200_128bit.xml index 122ea9af..838ee7f7 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_256Mb_WIDEIO-200_128bit.xml +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_256Mb_WIDEIO-200_128bit.xml @@ -28,8 +28,8 @@ - - + + diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_256Mb_WIDEIO-266_128bit.xml b/DRAMSys/library/resources/configs/memspecs/JEDEC_256Mb_WIDEIO-266_128bit.xml index aebd11e8..39da583f 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_256Mb_WIDEIO-266_128bit.xml +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_256Mb_WIDEIO-266_128bit.xml @@ -28,8 +28,8 @@ - - + + diff --git a/DRAMSys/library/src/configuration/ConfigurationLoader.cpp b/DRAMSys/library/src/configuration/ConfigurationLoader.cpp index 36f8ee10..42bf68cf 100644 --- a/DRAMSys/library/src/configuration/ConfigurationLoader.cpp +++ b/DRAMSys/library/src/configuration/ConfigurationLoader.cpp @@ -408,12 +408,12 @@ void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *xmlSpec) memSpec->tRC = clk * queryUIntParameter(timings, "RC"); memSpec->tRCD = clk * queryUIntParameter(timings, "RCD"); memSpec->tRL = clk * queryUIntParameter(timings, "RL"); - memSpec->tRTP = clk * queryUIntParameter(timings, "RTP"); memSpec->tWL = clk * queryUIntParameter(timings, "WL"); memSpec->tWR = clk * queryUIntParameter(timings, "WR"); memSpec->tXP = clk * queryUIntParameter(timings, "XP"); memSpec->tXS = clk * queryUIntParameter(timings, "XS"); - memSpec->tCCD = clk * queryUIntParameter(timings, "CCD"); + memSpec->tCCD_R = clk * queryUIntParameter(timings, "CCD_R"); + memSpec->tCCD_W = clk * queryUIntParameter(timings, "CCD_W"); memSpec->tREFI = clk * queryUIntParameter(timings, "REFI"); memSpec->tRFC = clk * queryUIntParameter(timings, "RFC"); memSpec->tRP = clk * queryUIntParameter(timings, "RP"); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp index c1380122..5ea73ad9 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp @@ -66,19 +66,17 @@ sc_time MemSpecWideIO::getExecutionTime(Command command) const return tRP; else if (command == Command::ACT) return tRCD; - else if (command == Command::RD) + else if (command == Command::RD || command == Command::RDA) return tRL + getReadAccessTime(); - else if (command == Command::RDA) - // this time is wrong (controller internally waits for tRAS) - return tRTP + tRP; - else if (command == Command::WR) +// else if (command == Command::RDA) +// // this time is wrong (controller internally waits for tRAS) +// return tRTP + tRP; + else if (command == Command::WR || command == Command::WRA) return tWL + getWriteAccessTime(); - else if (command == Command::WRA) - return tWL + getWriteAccessTime() + tWR + tRP; +// else if (command == Command::WRA) +// return tWL + getWriteAccessTime() + tWR + tRP; else if (command == Command::REFA) return tRFC; - else if (command == Command::REFB) - return tRFC; else { SC_REPORT_FATAL("getExecutionTime", diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h index 5fe55613..7185b25a 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h @@ -47,7 +47,6 @@ struct MemSpecWideIO : public MemSpec sc_time tRC; // RAS-cycle-time (min time bw 2 succesive ACT to same bank) sc_time tRCD; // act -> read/write sc_time tRL; // read latency (read command start to data strobe) - sc_time tRTP; // read to precharge sc_time tWL; // write latency sc_time tWR; // write recovery (write to precharge) sc_time tXP; // min delay to row access command after pdnpx pdnax @@ -56,7 +55,8 @@ struct MemSpecWideIO : public MemSpec sc_time tRFC; sc_time tRP; sc_time tDQSCK; - sc_time tCCD; + sc_time tCCD_R; + sc_time tCCD_W; sc_time tRRD; sc_time tTAW; sc_time tWTR; diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp index 5ac42425..14b4caf8 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp @@ -204,9 +204,8 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); } else - { reportFatal("CheckerDDR3", "Unknown command!"); - } + // Check if command bus is free earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp index 80081016..ba999d03 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp @@ -41,13 +41,6 @@ CheckerDDR4::CheckerDDR4() if (memSpec == nullptr) SC_REPORT_FATAL("CheckerDDR4", "Wrong MemSpec chosen"); - if (config.ControllerCoreRefDisable) - refreshChecker = new RefreshCheckerDDR4Dummy(memSpec); - else if (config.BankwiseLogic) - refreshChecker = new RefreshCheckerDDR4Bankwise(memSpec); - else - refreshChecker = new RefreshCheckerDDR4(memSpec); - lastScheduledByCommandAndBank = std::vector> (numberOfCommands(), std::vector(memSpec->NumberOfBanks)); lastScheduledByCommandAndBankGroup = std::vector> @@ -61,11 +54,6 @@ CheckerDDR4::CheckerDDR4() burstClocks = (memSpec->BurstLength / 2) * memSpec->clk; } -CheckerDDR4::~CheckerDDR4() -{ - delete refreshChecker; -} - sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const { sc_time lastCommandStart; @@ -86,6 +74,10 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); @@ -102,14 +94,8 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - if (lastActivates[rank.ID()].size() >= 4) earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW); - - refreshChecker->delayToSatisfyACT(bank, earliestTimeToStart); } else if (command == Command::RD || command == Command::RDA) { @@ -151,8 +137,6 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + burstClocks + memSpec->tWTR_S); - - refreshChecker->delayToSatisfyRD(bank, earliestTimeToStart); } else if (command == Command::WR || command == Command::WRA) { @@ -184,8 +168,6 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG lastCommandStart = lastScheduledByCommand[Command::WRA]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); - - refreshChecker->delayToSatisfyWR(bank, earliestTimeToStart); } else if (command == Command::PRE) { @@ -200,15 +182,62 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + burstClocks + memSpec->tWR); + } + else if (command == Command::PREA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); - refreshChecker->delayToSatisfyPRE(bank, earliestTimeToStart); + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + + burstClocks + memSpec->tWR); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + + burstClocks + memSpec->tWR); + } + else if (command == Command::REFA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + + burstClocks + memSpec->tWR + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); } else - { reportFatal("CheckerDDR4", "Unknown command!"); - } + // Check if command bus is free - earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->clk); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk); return (earliestTimeToStart - sc_time_stamp()); } @@ -222,7 +251,7 @@ void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank b lastScheduledByCommandAndBankGroup[command][bankgroup.ID()] = sc_time_stamp(); lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp(); lastScheduledByCommand[command] = sc_time_stamp(); - lastScheduled = sc_time_stamp(); + lastCommandOnBus = sc_time_stamp(); if (command == Command::ACT) { @@ -230,75 +259,4 @@ void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank b lastActivates[rank.ID()].pop(); lastActivates[rank.ID()].push(sc_time_stamp()); } - else if (command == Command::REFA || command == Command::REFB) - refreshChecker->insert(bank); -} - -// TODO: max(earliestTimeToStart, ...) needed? -void RefreshCheckerDDR4::delayToSatisfyACT(Bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timeForNextPREA - memSpec->tRAS)) - earliestTimeToStart = timeForNextREFA + memSpec->tRFC; -} - -void RefreshCheckerDDR4::delayToSatisfyRD(Bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timeForNextPREA - memSpec->tRTP)) - earliestTimeToStart = timeForNextREFA + memSpec->tRFC; -} - -void RefreshCheckerDDR4::delayToSatisfyWR(Bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timeForNextPREA - memSpec->tWL - burstClocks - memSpec->tWR)) - earliestTimeToStart = timeForNextREFA + memSpec->tRFC; -} - -void RefreshCheckerDDR4::delayToSatisfyPRE(Bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= timeForNextPREA) - earliestTimeToStart = timeForNextREFA + memSpec->tRFC; -} - -void RefreshCheckerDDR4::insert(Bank) -{ - timeForNextREFA += memSpec->tREFI; - timeForNextPREA += memSpec->tREFI; -} - -RefreshCheckerDDR4Bankwise::RefreshCheckerDDR4Bankwise(const MemSpecDDR4 *memSpec) - : RefreshCheckerDDR4Dummy(memSpec) -{ - sc_time currentREFB = memSpec->tREFI - memSpec->clk * (memSpec->NumberOfBanks - 1); - sc_time currentPRE = currentREFB - std::max(memSpec->clk * memSpec->NumberOfBanks, memSpec->tRP); - for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++) - { - timesForNextREFB.push_back(currentREFB); - timesForNextPRE.push_back(currentPRE); - currentREFB += memSpec->clk; - currentPRE += memSpec->clk; - } -} - -void RefreshCheckerDDR4Bankwise::delayToSatisfyACT(Bank bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tRAS)) - earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC; -} - -void RefreshCheckerDDR4Bankwise::delayToSatisfyRD(Bank bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tRTP)) - earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC; -} - -void RefreshCheckerDDR4Bankwise::delayToSatisfyWR(Bank bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tWL - burstClocks - memSpec->tWR)) - earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC; -} - -void RefreshCheckerDDR4Bankwise::insert(Bank bank) -{ - timesForNextREFB[bank.ID()] += memSpec->tREFI; - timesForNextPRE[bank.ID()] += memSpec->tREFI; } diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR4.h b/DRAMSys/library/src/controller/checker/CheckerDDR4.h index 581c4821..9c1cc8f6 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.h @@ -41,13 +41,10 @@ #include "../../configuration/memspec/MemSpecDDR4.h" #include "../../configuration/Configuration.h" -class RefreshCheckerDDR4Dummy; - class CheckerDDR4 final : public CheckerIF { public: CheckerDDR4(); - ~CheckerDDR4(); sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const; void insert(Command, Rank, BankGroup, Bank); @@ -58,70 +55,15 @@ private: std::vector> lastScheduledByCommandAndBankGroup; std::vector> lastScheduledByCommandAndRank; std::vector lastScheduledByCommand; - sc_time lastScheduled; + sc_time lastCommandOnBus; // Four activate window std::vector> lastActivates; - RefreshCheckerDDR4Dummy *refreshChecker; - sc_time burstClocks; // PowerDown TODO: Implement this method? //sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const; }; -class RefreshCheckerDDR4Dummy -{ -protected: - friend class CheckerDDR4; - RefreshCheckerDDR4Dummy(const MemSpecDDR4 *memSpec) : memSpec(memSpec) - { - burstClocks = (memSpec->BurstLength / 2) * memSpec->clk; - } - virtual ~RefreshCheckerDDR4Dummy() {} - - virtual void delayToSatisfyACT(Bank, sc_time &) {} - virtual void delayToSatisfyRD(Bank, sc_time &) {} - virtual void delayToSatisfyWR(Bank, sc_time &) {} - virtual void delayToSatisfyPRE(Bank, sc_time &) {} - virtual void insert(Bank) {} - - const MemSpecDDR4 *memSpec; - - sc_time burstClocks; -}; - -class RefreshCheckerDDR4 final : public RefreshCheckerDDR4Dummy -{ -private: - friend class CheckerDDR4; - RefreshCheckerDDR4(const MemSpecDDR4 *memSpec) - : RefreshCheckerDDR4Dummy(memSpec) {} - - void delayToSatisfyACT(Bank, sc_time &); - void delayToSatisfyRD(Bank, sc_time &); - void delayToSatisfyWR(Bank, sc_time &); - void delayToSatisfyPRE(Bank, sc_time &); - void insert(Bank); - - sc_time timeForNextREFA = memSpec->tREFI; - sc_time timeForNextPREA = timeForNextREFA - memSpec->tRP; -}; - -class RefreshCheckerDDR4Bankwise final : public RefreshCheckerDDR4Dummy -{ -private: - friend class CheckerDDR4; - RefreshCheckerDDR4Bankwise(const MemSpecDDR4 *); - - void delayToSatisfyACT(Bank, sc_time &); - void delayToSatisfyRD(Bank, sc_time &); - void delayToSatisfyWR(Bank, sc_time &); - void insert(Bank); - - std::vector timesForNextREFB; - std::vector timesForNextPRE; -}; - #endif // CHECKERDDR4_H diff --git a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h index 8bd46f3f..a8ca0002 100644 --- a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h +++ b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h @@ -41,8 +41,6 @@ #include "../../configuration/memspec/MemSpecLPDDR4.h" #include "../../configuration/Configuration.h" -class RefreshCheckerLPDDR4Dummy; - class CheckerLPDDR4 final : public CheckerIF { public: diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp b/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp index 065f954a..c0ac78a7 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp @@ -41,13 +41,6 @@ CheckerWideIO::CheckerWideIO() if (memSpec == nullptr) SC_REPORT_FATAL("CheckerWideIO", "Wrong MemSpec chosen"); - if (config.ControllerCoreRefDisable) - refreshChecker = new RefreshCheckerWideIODummy(memSpec); - else if (config.BankwiseLogic) - refreshChecker = new RefreshCheckerWideIOBankwise(memSpec); - else - refreshChecker = new RefreshCheckerWideIO(memSpec); - lastScheduledByCommandAndBank = std::vector> (numberOfCommands(), std::vector(memSpec->NumberOfBanks)); lastScheduledByCommandAndRank = std::vector> @@ -55,11 +48,8 @@ CheckerWideIO::CheckerWideIO() lastScheduledByCommand = std::vector(numberOfCommands()); lastActivates = std::vector>(memSpec->NumberOfRanks); -} -CheckerWideIO::~CheckerWideIO() -{ - delete refreshChecker; + burstClocks = memSpec->BurstLength * memSpec->clk; } sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const @@ -71,16 +61,21 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban { lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + + burstClocks - memSpec->clk + memSpec->tWR + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); @@ -93,14 +88,8 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - if (lastActivates[rank.ID()].size() >= 2) earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tTAW); - - refreshChecker->delayToSatisfyACT(bank, earliestTimeToStart); } else if (command == Command::RD || command == Command::RDA) { @@ -109,13 +98,21 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban lastCommandStart = lastScheduledByCommand[Command::RD]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks); + + lastCommandStart = lastScheduledByCommand[Command::RDA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks); lastCommandStart = lastScheduledByCommand[Command::WR]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWTR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + + memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWTR); - refreshChecker->delayToSatisfyRD(bank, earliestTimeToStart); + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + + memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWTR); } else if (command == Command::WR || command == Command::WRA) { @@ -124,13 +121,21 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban lastCommandStart = lastScheduledByCommand[Command::RD]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + + memSpec->tRL + burstClocks + memSpec->clk); + + lastCommandStart = lastScheduledByCommand[Command::RDA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + + memSpec->tRL + burstClocks + memSpec->clk); lastCommandStart = lastScheduledByCommand[Command::WR]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks); - refreshChecker->delayToSatisfyWR(bank, earliestTimeToStart); + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks); } else if (command == Command::PRE) { @@ -139,13 +144,62 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks); lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + + memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWR); + } + else if (command == Command::PREA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); - refreshChecker->delayToSatisfyPRE(bank, earliestTimeToStart); + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + + memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWR); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + + memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWR); + } + else if (command == Command::REFA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + + memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWR + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); } else { @@ -173,75 +227,4 @@ void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank) lastActivates[rank.ID()].pop(); lastActivates[rank.ID()].push(sc_time_stamp()); } - else if (command == Command::REFA || command == Command::REFB) - refreshChecker->insert(bank); -} - -// TODO: max(earliestTimeToStart, ...) needed? -void RefreshCheckerWideIO::delayToSatisfyACT(Bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timeForNextPREA - memSpec->tRAS)) - earliestTimeToStart = timeForNextREFA + memSpec->tRFC; -} - -void RefreshCheckerWideIO::delayToSatisfyRD(Bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timeForNextPREA - memSpec->tRTP)) - earliestTimeToStart = timeForNextREFA + memSpec->tRFC; -} - -void RefreshCheckerWideIO::delayToSatisfyWR(Bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timeForNextPREA - memSpec->tWL - memSpec->tCCD - memSpec->tWR)) - earliestTimeToStart = timeForNextREFA + memSpec->tRFC; -} - -void RefreshCheckerWideIO::delayToSatisfyPRE(Bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= timeForNextPREA) - earliestTimeToStart = timeForNextREFA + memSpec->tRFC; -} - -void RefreshCheckerWideIO::insert(Bank) -{ - timeForNextREFA += memSpec->tREFI; - timeForNextPREA += memSpec->tREFI; -} - -RefreshCheckerWideIOBankwise::RefreshCheckerWideIOBankwise(const MemSpecWideIO *memSpec) - : RefreshCheckerWideIODummy(memSpec) -{ - sc_time currentREFB = memSpec->tREFI - memSpec->clk * (memSpec->NumberOfBanks - 1); - sc_time currentPRE = currentREFB - std::max(memSpec->clk * memSpec->NumberOfBanks, memSpec->tRP); - for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++) - { - timesForNextREFB.push_back(currentREFB); - timesForNextPRE.push_back(currentPRE); - currentREFB += memSpec->clk; - currentPRE += memSpec->clk; - } -} - -void RefreshCheckerWideIOBankwise::delayToSatisfyACT(Bank bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tRAS)) - earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC; -} - -void RefreshCheckerWideIOBankwise::delayToSatisfyRD(Bank bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tRTP)) - earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC; -} - -void RefreshCheckerWideIOBankwise::delayToSatisfyWR(Bank bank, sc_time &earliestTimeToStart) -{ - if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tWL - memSpec->tCCD - memSpec->tWR)) - earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC; -} - -void RefreshCheckerWideIOBankwise::insert(Bank bank) -{ - timesForNextREFB[bank.ID()] += memSpec->tREFI; - timesForNextPRE[bank.ID()] += memSpec->tREFI; } diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO.h b/DRAMSys/library/src/controller/checker/CheckerWideIO.h index 58fb4560..bb90da75 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO.h +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO.h @@ -41,13 +41,10 @@ #include "../../configuration/memspec/MemSpecWideIO.h" #include "../../configuration/Configuration.h" -class RefreshCheckerWideIODummy; - class CheckerWideIO final : public CheckerIF { public: CheckerWideIO(); - ~CheckerWideIO(); sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const; void insert(Command, Rank, BankGroup, Bank); @@ -62,58 +59,10 @@ private: // Four activate window std::vector> lastActivates; - RefreshCheckerWideIODummy *refreshChecker; + sc_time burstClocks; // PowerDown TODO: Implement this method? //sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const; }; -class RefreshCheckerWideIODummy -{ -protected: - friend class CheckerWideIO; - RefreshCheckerWideIODummy(const MemSpecWideIO *memSpec) : memSpec(memSpec) {} - virtual ~RefreshCheckerWideIODummy() {} - - virtual void delayToSatisfyACT(Bank, sc_time &) {} - virtual void delayToSatisfyRD(Bank, sc_time &) {} - virtual void delayToSatisfyWR(Bank, sc_time &) {} - virtual void delayToSatisfyPRE(Bank, sc_time &) {} - virtual void insert(Bank) {} - - const MemSpecWideIO *memSpec; -}; - -class RefreshCheckerWideIO final : public RefreshCheckerWideIODummy -{ -private: - friend class CheckerWideIO; - RefreshCheckerWideIO(const MemSpecWideIO *memSpec) - : RefreshCheckerWideIODummy(memSpec) {} - - void delayToSatisfyACT(Bank, sc_time &); - void delayToSatisfyRD(Bank, sc_time &); - void delayToSatisfyWR(Bank, sc_time &); - void delayToSatisfyPRE(Bank, sc_time &); - void insert(Bank); - - sc_time timeForNextREFA = memSpec->tREFI; - sc_time timeForNextPREA = timeForNextREFA - memSpec->tRP; -}; - -class RefreshCheckerWideIOBankwise final : public RefreshCheckerWideIODummy -{ -private: - friend class CheckerWideIO; - RefreshCheckerWideIOBankwise(const MemSpecWideIO *); - - void delayToSatisfyACT(Bank, sc_time &); - void delayToSatisfyRD(Bank, sc_time &); - void delayToSatisfyWR(Bank, sc_time &); - void insert(Bank); - - std::vector timesForNextREFB; - std::vector timesForNextPRE; -}; - #endif // CHECKERWIDEIO_H diff --git a/DRAMSys/library/src/simulation/DramWideIO.cpp b/DRAMSys/library/src/simulation/DramWideIO.cpp index 98699d02..1eb2390f 100644 --- a/DRAMSys/library/src/simulation/DramWideIO.cpp +++ b/DRAMSys/library/src/simulation/DramWideIO.cpp @@ -77,9 +77,9 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) memTimingSpec.RRDB_L = memSpec->tRRD / clk; memTimingSpec.RRDB_S = memSpec->tRRD / clk; memTimingSpec.AL = 0; - memTimingSpec.CCD = memSpec->tCCD / clk; - memTimingSpec.CCD_L = memSpec->tCCD / clk; - memTimingSpec.CCD_S = memSpec->tCCD / clk; + memTimingSpec.CCD = memSpec->BurstLength; + memTimingSpec.CCD_L = memSpec->BurstLength; + memTimingSpec.CCD_S = memSpec->BurstLength; memTimingSpec.CKE = memSpec->tCKE / clk; memTimingSpec.CKESR = memSpec->tCKESR / clk; memTimingSpec.clkMhz = memSpec->clkMHz; @@ -97,7 +97,7 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) memTimingSpec.RRD = memSpec->tRRD / clk; memTimingSpec.RRD_L = memSpec->tRRD / clk; memTimingSpec.RRD_S = memSpec->tRRD / clk; - memTimingSpec.RTP = memSpec->tRTP / clk; + memTimingSpec.RTP = memSpec->BurstLength; memTimingSpec.TAW = memSpec->tTAW / clk; memTimingSpec.WL = memSpec->tWL / clk; memTimingSpec.WR = memSpec->tWR / clk;