Added new CheckerDDR3, changed checker type in controller to CheckerIF for polymorphism.

This commit is contained in:
Lukas Steiner (2)
2019-07-30 16:25:05 +02:00
parent 1053f7c1b7
commit ed96f9fb54
10 changed files with 274 additions and 14 deletions

View File

@@ -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)

View File

@@ -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()

View File

@@ -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<Command, tlm_generic_payload *> 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

View File

@@ -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);
}

View File

@@ -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<Bank, BankMachine *> bankMachines;
CmdMuxIF *commandMux;
SchedulerIF *scheduler;
CheckerDDR3New *checker;
CheckerIF *checker;
void releasePayload();
void acquirePayload();

View File

@@ -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)

View File

@@ -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());
}
}

View File

@@ -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 <queue>
#include "../core/configuration/MemSpec.h"
#include "../core/configuration/Configuration.h"
class CheckerDDR3 final : public CheckerIF
{
public:
CheckerDDR3()
{
memSpec = dynamic_cast<MemSpecDDR3 *>(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<sc_time> lastActivates;
sc_time timeToSatisfyFAW();
// PowerDown TODO: Implement this method?
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
};
#endif // CHECKERDDR3_H

View File

@@ -1,2 +0,0 @@
#include "CheckerIF.h"

View File

@@ -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