From ed96f9fb54de7911075ab2657373407ca0ace940 Mon Sep 17 00:00:00 2001 From: "Lukas Steiner (2)" Date: Tue, 30 Jul 2019 16:25:05 +0200 Subject: [PATCH] Added new CheckerDDR3, changed checker type in controller to CheckerIF for polymorphism. --- DRAMSys/library/library.pro | 5 +- .../library/src/controller/BankMachine.cpp | 2 +- DRAMSys/library/src/controller/BankMachine.h | 8 +- .../library/src/controller/ControllerNew.cpp | 5 +- .../library/src/controller/ControllerNew.h | 6 +- .../src/controller/ControllerRecordable.cpp | 1 + .../src/controller/checker/CheckerDDR3.cpp | 189 ++++++++++++++++++ .../src/controller/checker/CheckerDDR3.h | 67 +++++++ .../src/controller/checker/CheckerIF.cpp | 2 - .../src/controller/checker/CheckerIF.h | 3 + 10 files changed, 274 insertions(+), 14 deletions(-) create mode 100644 DRAMSys/library/src/controller/checker/CheckerDDR3.cpp create mode 100644 DRAMSys/library/src/controller/checker/CheckerDDR3.h delete mode 100644 DRAMSys/library/src/controller/checker/CheckerIF.cpp diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index 386605e1..605871bb 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -156,7 +156,7 @@ SOURCES += \ src/controller/cmdmux/CmdMuxStrict.cpp \ src/controller/cmdmux/CmdMuxOldest.cpp \ src/controller/ControllerRecordable.cpp \ - src/controller/checker/CheckerIF.cpp + src/controller/checker/CheckerDDR3.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -248,7 +248,8 @@ HEADERS += \ src/controller/cmdmux/CmdMuxStrict.h \ src/controller/cmdmux/CmdMuxOldest.h \ src/controller/ControllerRecordable.h \ - src/controller/checker/CheckerIF.h + src/controller/checker/CheckerIF.h \ + src/controller/checker/CheckerDDR3.h #src/common/third_party/json/include/nlohmann/json.hpp \ thermalsim = $$(THERMALSIM) diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 36ea5414..e29200c0 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -34,7 +34,7 @@ #include "BankMachine.h" -BankMachine::BankMachine(SchedulerIF *scheduler, CheckerDDR3New *checker, Bank bank) +BankMachine::BankMachine(SchedulerIF *scheduler, CheckerIF *checker, Bank bank) : scheduler(scheduler), checker(checker), bank(bank) {} sc_time BankMachine::startBankMachine() diff --git a/DRAMSys/library/src/controller/BankMachine.h b/DRAMSys/library/src/controller/BankMachine.h index dc561680..77eeec72 100644 --- a/DRAMSys/library/src/controller/BankMachine.h +++ b/DRAMSys/library/src/controller/BankMachine.h @@ -42,12 +42,12 @@ #include "ControllerNew.h" #include "Command.h" #include "scheduler/SchedulerIF.h" -#include "core/scheduling/checker/CheckerDDR3New.h" +#include "checker/CheckerIF.h" using namespace tlm; class SchedulerIF; -class CheckerDDR3New; +class CheckerIF; enum class BmState { @@ -58,7 +58,7 @@ enum class BmState class BankMachine { public: - BankMachine(SchedulerIF *, CheckerDDR3New*, Bank); + BankMachine(SchedulerIF *, CheckerIF*, Bank); sc_time startBankMachine(); std::pair getNextCommand(); void updateState(Command); @@ -74,7 +74,7 @@ private: Command nextCommand = Command::NOP; sc_time timeToSchedule = SC_ZERO_TIME; SchedulerIF *scheduler; - CheckerDDR3New *checker; + CheckerIF *checker; }; #endif // BANKMACHINE_H diff --git a/DRAMSys/library/src/controller/ControllerNew.cpp b/DRAMSys/library/src/controller/ControllerNew.cpp index f0ace2e7..79b5104f 100644 --- a/DRAMSys/library/src/controller/ControllerNew.cpp +++ b/DRAMSys/library/src/controller/ControllerNew.cpp @@ -42,6 +42,7 @@ #include "../common/dramExtensions.h" #include "../common/protocol.h" #include "core/scheduling/ScheduledCommand.h" +#include "checker/CheckerDDR3.h" ControllerNew::ControllerNew(sc_module_name name) : sc_module(name), debugManager(&DebugManager::getInstance()) @@ -54,7 +55,7 @@ ControllerNew::ControllerNew(sc_module_name name) : tSocket.register_transport_dbg(this, &ControllerNew::transport_dbg); iSocket.register_nb_transport_bw(this, &ControllerNew::nb_transport_bw); - checker = new CheckerDDR3New(); + checker = new CheckerDDR3(); scheduler = new SchedulerFifo(); for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++) bankMachines[Bank(bankID)] = new BankMachine(scheduler, checker, Bank(bankID)); @@ -116,7 +117,7 @@ unsigned int ControllerNew::transport_dbg(tlm_generic_payload &) return 0; } -void ControllerNew::printDebugMessage(string message) +void ControllerNew::printDebugMessage(std::string message) { debugManager->printDebugMessage(name(), message); } diff --git a/DRAMSys/library/src/controller/ControllerNew.h b/DRAMSys/library/src/controller/ControllerNew.h index e1dd1c0f..0b852661 100644 --- a/DRAMSys/library/src/controller/ControllerNew.h +++ b/DRAMSys/library/src/controller/ControllerNew.h @@ -48,7 +48,7 @@ #include "cmdmux/CmdMuxIF.h" #include "scheduler/SchedulerIF.h" #include "../common/DebugManager.h" -#include "core/scheduling/checker/CheckerDDR3New.h" +#include "checker/CheckerIF.h" using namespace tlm; @@ -75,7 +75,7 @@ protected: virtual void sendToFrontend(tlm_generic_payload *, tlm_phase); virtual void sendToDram(Command, tlm_generic_payload *); - void printDebugMessage(string message); + void printDebugMessage(std::string message); private: unsigned numberOfPayloads = 0; @@ -90,7 +90,7 @@ private: std::map bankMachines; CmdMuxIF *commandMux; SchedulerIF *scheduler; - CheckerDDR3New *checker; + CheckerIF *checker; void releasePayload(); void acquirePayload(); diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 95f101a1..8457f5e7 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -35,6 +35,7 @@ #include "ControllerRecordable.h" #include "../common/protocol.h" +#include "core/configuration/Configuration.h" tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp new file mode 100644 index 00000000..6dc57d5d --- /dev/null +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2019, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Lukas Steiner + */ + +#include "CheckerDDR3.h" + +sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Bank bank) +{ + ScheduledCommand lastCommand; + + sc_time minTimeToWait = sc_time_stamp(); + + if (command == Command::ACT) + { + lastCommand = lastScheduledByCommandAndBank[Command::RDA][bank]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRTP + memSpec->tRP); + + lastCommand = lastScheduledByCommandAndBank[Command::WRA][bank]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP); + + lastCommand = lastScheduledByCommandAndBank[Command::PRE][bank]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRP); + + lastCommand = lastScheduledByCommand[Command::PREA]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRP); + + lastCommand = lastScheduledByCommand[Command::PDXA]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); + + lastCommand = lastScheduledByCommand[Command::PDXP]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); + + lastCommand = lastScheduledByCommand[Command::REFA]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRFC); + + lastCommand = lastScheduledByCommand[Command::SREFEX]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tXS); + + lastCommand = lastScheduledByCommandAndBank[Command::ACT][bank]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRC); + + lastCommand = lastScheduledByCommand[Command::ACT]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRRD); + + minTimeToWait = std::max(minTimeToWait, timeToSatisfyFAW()); + } + else if (command == Command::RD || command == Command::RDA) + { + lastCommand = lastScheduledByCommandAndBank[Command::ACT][bank]; + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRCD); + + lastCommand = lastScheduledByCommand[Command::PDXA]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); + + lastCommand = lastScheduledByCommand[Command::SREFEX]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tXSDLL); + + lastCommand = lastScheduledByCommand[Command::RD]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD); + + lastCommand = lastScheduledByCommand[Command::WR]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWTR); + } + else if (command == Command::WR || command == Command::WRA) + { + lastCommand = lastScheduledByCommandAndBank[Command::ACT][bank]; + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRCD); + + lastCommand = lastScheduledByCommand[Command::PDXA]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); + + lastCommand = lastScheduledByCommand[Command::SREFEX]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tXSDLL); + + lastCommand = lastScheduledByCommand[Command::RD]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL); + + lastCommand = lastScheduledByCommand[Command::WR]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD); + } + else if (command == Command::PRE) + { + lastCommand = lastScheduledByCommandAndBank[Command::ACT][bank]; + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRAS); + + lastCommand = lastScheduledByCommandAndBank[Command::RD][bank]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tRTP); + + lastCommand = lastScheduledByCommandAndBank[Command::WR][bank]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWR); + + lastCommand = lastScheduledByCommand[Command::PDXA]; + if (lastCommand.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); + } + else + { + reportFatal("CheckerDDR3", "Unknown command!"); + } + // Check if bus is free + if (lastScheduled.isValidCommand()) + minTimeToWait = std::max(minTimeToWait, lastScheduled.getStart() + memSpec->clk); + + return (minTimeToWait - sc_time_stamp()); +} + +sc_time CheckerDDR3::timeToSatisfyFAW() +{ + if (lastActivates.size() < 4) + return sc_time_stamp(); + else + { + sc_time earliestTime = lastActivates.front() + memSpec->tFAW; + if (earliestTime > sc_time_stamp()) + return earliestTime; + else + return sc_time_stamp(); + } +} + +void CheckerDDR3::insert(const ScheduledCommand &scheduledCommand) +{ + Command command = scheduledCommand.getCommand(); + printDebugMessage("Changing state on bank " + + to_string(scheduledCommand.getBank().ID()) + + " command is " + commandToString(command)); + + lastScheduledByCommandAndBank[command][scheduledCommand.getBank()] = scheduledCommand; + lastScheduledByCommand[command] = scheduledCommand; + lastScheduled = scheduledCommand; + + // TODO: implement FAW for ACTB + if (command == Command::ACT) + { + if (lastActivates.size() == 4) + lastActivates.pop(); + lastActivates.push(scheduledCommand.getStart()); + } +} diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.h b/DRAMSys/library/src/controller/checker/CheckerDDR3.h new file mode 100644 index 00000000..e17750b2 --- /dev/null +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Lukas Steiner + */ + +#ifndef CHECKERDDR3_H +#define CHECKERDDR3_H + +#include "CheckerIF.h" +#include +#include "../core/configuration/MemSpec.h" +#include "../core/configuration/Configuration.h" + +class CheckerDDR3 final : public CheckerIF +{ +public: + CheckerDDR3() + { + memSpec = dynamic_cast(Configuration::getInstance().memSpec); + if (memSpec == nullptr) + SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen"); + } + + sc_time delayToSatisfyConstraints(Command, Bank); + void insert(const ScheduledCommand &); + +private: + const MemSpecDDR3 *memSpec; + + // Four activate window + std::queue lastActivates; + sc_time timeToSatisfyFAW(); + + // PowerDown TODO: Implement this method? + //sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const; +}; + +#endif // CHECKERDDR3_H diff --git a/DRAMSys/library/src/controller/checker/CheckerIF.cpp b/DRAMSys/library/src/controller/checker/CheckerIF.cpp deleted file mode 100644 index fd5f6059..00000000 --- a/DRAMSys/library/src/controller/checker/CheckerIF.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "CheckerIF.h" - diff --git a/DRAMSys/library/src/controller/checker/CheckerIF.h b/DRAMSys/library/src/controller/checker/CheckerIF.h index 015a1cd8..1d0c6b70 100644 --- a/DRAMSys/library/src/controller/checker/CheckerIF.h +++ b/DRAMSys/library/src/controller/checker/CheckerIF.h @@ -59,6 +59,9 @@ protected: { DebugManager::getInstance().printDebugMessage("Checker", message); } + + // PowerDown TODO: Implement this method? + //sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const; }; #endif // CHECKERIF_H