Removed unused files of old controller.

This commit is contained in:
Lukas Steiner (2)
2019-08-12 14:19:22 +02:00
parent 05a8272ee6
commit e6dc4e7c75
67 changed files with 9 additions and 6940 deletions

View File

@@ -92,35 +92,13 @@ SOURCES += \
src/controller/core/powerdown/PowerDownManagerTimeout.cpp \
src/controller/core/powerdown/PowerDownManagerBankwise.cpp \
src/controller/core/powerdown/PowerDownManager.cpp \
src/controller/scheduler/FrFcfs.cpp \
src/controller/scheduler/Fifo.cpp \
src/controller/scheduler/SMS.cpp \
src/controller/core/refresh/RefreshManagerBankwise.cpp \
src/controller/core/refresh/RefreshManager.cpp \
src/controller/core/refresh/RGR.cpp \
src/controller/core/scheduling/checker/WriteChecker.cpp \
src/controller/core/scheduling/checker/RefreshChecker.cpp \
src/controller/core/scheduling/checker/ReadChecker.cpp \
src/controller/core/scheduling/checker/PrechargeChecker.cpp \
src/controller/core/scheduling/checker/PrechargeAllChecker.cpp \
src/controller/core/scheduling/checker/PowerDownChecker.cpp \
src/controller/core/scheduling/checker/ActivateChecker.cpp \
src/controller/core/scheduling/checker/PreBChecker.cpp \
src/controller/core/scheduling/checker/ActBChecker.cpp \
src/controller/core/scheduling/ScheduledCommand.cpp \
src/controller/core/Slots.cpp \
src/controller/core/ControllerCore.cpp \
src/simulation/MemoryManager.cpp \
src/simulation/TemperatureController.cpp \
src/controller/core/configuration/ConfigurationLoader.cpp \
src/controller/core/powerdown/NoPowerDown.cpp \
src/controller/Command.cpp \
src/controller/ControllerState.cpp \
src/controller/RowBufferStates.cpp \
src/controller/scheduler/IScheduler.cpp \
src/controller/scheduler/FifoStrict.cpp \
src/error/errormodel.cpp \
src/controller/Controller.cpp \
src/simulation/TracePlayer.cpp \
src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \
src/simulation/TraceSetup.cpp \
@@ -131,10 +109,6 @@ SOURCES += \
src/error/ECC/Word.cpp \
src/error/eccbaseclass.cpp \
src/error/ecchamming.cpp \
src/controller/scheduler/FrFcfsRp.cpp \
src/controller/scheduler/FrFcfsGrp.cpp \
src/controller/scheduler/Grp.cpp \
src/controller/RecordableController.cpp \
src/common/AddressDecoder.cpp \
src/simulation/Dram.cpp \
src/simulation/Arbiter.cpp \
@@ -148,7 +122,6 @@ SOURCES += \
src/simulation/DramRecordable.cpp \
src/simulation/DramWideIO.cpp \
src/controller/core/configuration/MemSpec.cpp \
src/controller/core/scheduling/checker/CheckerDDR3New.cpp \
src/controller/BankMachine.cpp \
src/controller/ControllerNew.cpp \
src/controller/scheduler/SchedulerFifo.cpp \
@@ -170,27 +143,7 @@ HEADERS += \
src/controller/core/powerdown/PowerDownManagerTimeout.h \
src/controller/core/powerdown/PowerDownManagerBankwise.h \
src/controller/core/powerdown/PowerDownManager.h \
src/controller/scheduler/FrFcfs.h \
src/controller/scheduler/Fifo.h \
src/controller/scheduler/SMS.h \
src/controller/Controller.h \
src/controller/core/refresh/RefreshManagerBankwise.h \
src/controller/core/refresh/RefreshManager.h \
src/controller/core/refresh/IRefreshManager.h \
src/controller/core/refresh/RGR.h \
src/controller/core/scheduling/checker/WriteChecker.h \
src/controller/core/scheduling/checker/RefreshChecker.h \
src/controller/core/scheduling/checker/ReadChecker.h \
src/controller/core/scheduling/checker/PrechargeChecker.h \
src/controller/core/scheduling/checker/PrechargeAllChecker.h \
src/controller/core/scheduling/checker/PowerDownChecker.h \
src/controller/core/scheduling/checker/ICommandChecker.h \
src/controller/core/scheduling/checker/ActivateChecker.h \
src/controller/core/scheduling/checker/PreBChecker.h \
src/controller/core/scheduling/checker/ActBChecker.h \
src/controller/core/scheduling/ScheduledCommand.h \
src/controller/core/Slots.h \
src/controller/core/ControllerCore.h \
src/simulation/TracePlayer.h \
src/simulation/MemoryManager.h \
src/simulation/Dram.h \
@@ -204,12 +157,7 @@ HEADERS += \
src/simulation/TemperatureController.h \
src/controller/core/powerdown/NoPowerDown.h \
src/controller/Command.h \
src/controller/RowBufferStates.h \
src/controller/ControllerState.h \
src/controller/core/powerdown/IPowerDownManager.h \
src/controller/scheduler/IScheduler.h \
src/controller/scheduler/FifoStrict.h \
src/controller/IController.h \
src/controller/core/configuration/ConfigurationLoader.h \
src/error/errormodel.h \
src/simulation/ExampleInitiator.h \
@@ -222,12 +170,8 @@ HEADERS += \
src/error/ECC/Word.h \
src/error/eccbaseclass.h \
src/error/ecchamming.h \
src/controller/scheduler/FrFcfsRp.h \
src/controller/scheduler/FrFcfsGrp.h \
src/controller/scheduler/Grp.h \
src/simulation/IArbiter.h \
src/simulation/SimpleArbiter.h \
src/controller/RecordableController.h \
src/common/AddressDecoder.h \
src/common/CongenAddressDecoder.h \
src/common/XmlAddressDecoder.h \
@@ -240,7 +184,6 @@ HEADERS += \
src/simulation/DramRecordable.h \
src/simulation/DramWideIO.h \
src/controller/GenericController.h \
src/controller/core/scheduling/checker/CheckerDDR3New.h \
src/controller/BankMachine.h \
src/controller/ControllerNew.h \
src/controller/scheduler/SchedulerIF.h \

View File

@@ -44,7 +44,6 @@
#include "dramExtensions.h"
#include "XmlAddressDecoder.h"
#include "../controller/core/configuration/Configuration.h"
#include "../controller/Controller.h"
using namespace std;
@@ -146,8 +145,7 @@ void TlmRecorder::introduceTransactionSystem(tlm::tlm_generic_payload &trans)
currentTransactionsInSystem[&trans].dramExtension = DramExtension::getExtension(
trans);
if (DramExtension::getExtension(trans).getThread().ID() ==
Controller::ControllerThreadId())
if (DramExtension::getExtension(trans).getThread().ID() == UINT_MAX)
currentTransactionsInSystem[&trans].timeOfGeneration = SC_ZERO_TIME;
else
currentTransactionsInSystem[&trans].timeOfGeneration =
@@ -348,8 +346,7 @@ void TlmRecorder::insertGeneralInfo()
sqlite3_bind_int(insertGeneralInfoStatement, 10, 0);
sqlite3_bind_int(insertGeneralInfoStatement, 11, 0);
}
sqlite3_bind_int(insertGeneralInfoStatement, 12,
Controller::ControllerThreadId()); ;
sqlite3_bind_int(insertGeneralInfoStatement, 12, UINT_MAX);
executeSqlStatement(insertGeneralInfoStatement);
}

View File

@@ -40,7 +40,6 @@
#include <tlm.h>
#include <fstream>
#include "dramExtensions.h"
#include "../controller/Controller.h"
using namespace std;
using namespace tinyxml2;
@@ -236,7 +235,7 @@ string loadTextFileContents(string filename)
}
}
void setUpDummy(tlm::tlm_generic_payload &payload, Bank &bank)
void setUpDummy(tlm::tlm_generic_payload &payload, Bank bank)
{
payload.set_address(bank.getStartAddress());
payload.set_command(tlm::TLM_READ_COMMAND);
@@ -245,8 +244,8 @@ void setUpDummy(tlm::tlm_generic_payload &payload, Bank &bank)
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_streaming_width(0);
payload.set_extension(new DramExtension(Thread(Controller::ControllerThreadId()),
bank, BankGroup(0), Row(0), Column(0), 0, 0));
payload.set_extension(new DramExtension(Thread(UINT_MAX), bank, BankGroup(0),
Row(0), Column(0), 0, 0));
// payload takes ownership
// TODO: Dummies muessen noch banggruppe und rank sauber bekommen .. noch was ueberlegen!!!
}

View File

@@ -146,7 +146,7 @@ std::string queryStringParameter(tinyxml2::XMLElement *node, std::string name);
bool queryBoolParameter(tinyxml2::XMLElement *node, std::string name);
double queryDoubleParameter(tinyxml2::XMLElement *node, std::string name);
void setUpDummy(tlm::tlm_generic_payload &payload, Bank &bank);
void setUpDummy(tlm::tlm_generic_payload &payload, Bank bank = Bank(0));
#endif // UTILS_H

View File

@@ -51,6 +51,7 @@ enum class Command {
RDA,
WRA,
REFA,
REFB,
PDEA,
PDXA,
PDEP,

View File

@@ -1,648 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
* Felipe S. Prado
*/
#include "Controller.h"
#include <iostream>
#include "core/configuration/Configuration.h"
Controller::Controller(sc_module_name name) :
GenericController(name),
frontendPEQ(this, &Controller::frontendPEQCallback),
dramPEQ(this, &Controller::dramPEQCallback),
controllerCorePEQ(this, &Controller::controllerCorePEQCallback),
debugManager(DebugManager::getInstance())
{
controllerCore = new ControllerCore("core", *this, numberOfPayloadsInSystem);
buildScheduler();
}
Controller::~Controller()
{
// Bandwidth:
sc_time activeTime = numberOfTransactionsServed
* Configuration::getInstance().memSpec->BurstLength
/ Configuration::getInstance().memSpec->DataRate
* Configuration::getInstance().memSpec->clk;
sc_time idleTime = getIdleTime();
sc_time endTime = getEndTime();
sc_time startTime = getStartTime();
double bandwidth = (activeTime / (endTime - startTime) * 100);
double bandwidth_IDLE = ((activeTime) / (endTime - startTime - idleTime) * 100);
double maxBandwidth = (
// clk in Mhz e.g. 800 [MHz]:
(1000000 / Configuration::getInstance().memSpec->clk.to_double())
// DataRate e.g. 2
* Configuration::getInstance().memSpec->DataRate
// BusWidth e.g. 8 or 64
* Configuration::getInstance().memSpec->bitWidth
// Number of devices on a DIMM e.g. 8
* Configuration::getInstance().NumberOfDevicesOnDIMM ) / ( 1024 );
cout << name() << string(" Total Time: ")
<< (endTime - startTime).to_string()
<< endl;
cout << name() << string(" AVG BW: ")
<< std::fixed << std::setprecision(2)
<< ((bandwidth / 100)*maxBandwidth)
<< " Gibit/s (" << bandwidth << " %)"
<< endl;
cout << name() << string(" AVG BW/IDLE: ")
<< std::fixed << std::setprecision(2)
<< ((bandwidth_IDLE / 100)*maxBandwidth)
<< " Gibit/s (" << (bandwidth_IDLE) << " %)"
<< endl;
cout << name() << string(" MAX BW: ")
<< std::fixed << std::setprecision(2)
<< maxBandwidth << " Gibit/s"
<< endl;
delete controllerCore;
delete scheduler;
}
void Controller::buildScheduler()
{
string selectedScheduler = Configuration::getInstance().Scheduler;
if (selectedScheduler == "Fifo") {
scheduler = new Fifo(*controllerCore);
} else if (selectedScheduler == "FifoStrict") {
scheduler = new FifoStrict(*this, *controllerCore);
} else if (selectedScheduler == "FrFcfs") {
scheduler = new FrFcfs(*controllerCore);
} else if (selectedScheduler == "FrFcfsRp") {
scheduler = new FrFcfsRp(*controllerCore);
} else if (selectedScheduler == "FrFcfsGrp") {
scheduler = new FrFcfsGrp(*controllerCore, this);
} else if (selectedScheduler == "Grp") {
scheduler = new Grp(*controllerCore, this);
} else if (selectedScheduler == "SMS") {
scheduler = new SMS("SMS", *controllerCore,
Configuration::getInstance().SJFProbability);
}
//else if (selectedScheduler == "PAR_BS")
//{
// scheduler = new PAR_BS(*controllerCore,Configuration::getInstance().RefreshAwareScheduling,
// Configuration::getInstance().Capsize);
//}
// else if (selectedScheduler == "Grouper")
// {
// scheduler = new ReadWriteGrouper(*controllerCore);
// }
else
reportFatal(name(), "unsupported scheduler: " + selectedScheduler);
}
//Send the next scheduled command to the DRAM
void Controller::send(const ScheduledCommand &command,
tlm_generic_payload &payload)
{
sc_assert(command.getStart() >= sc_time_stamp());
tlm_phase phase;
switch (command.getCommand())
{
//TODO: refactor tlm recorder
case Command::RD:
phase = BEGIN_RD;
break;
case Command::RDA:
phase = BEGIN_RDA;
break;
case Command::WR:
phase = BEGIN_WR;
break;
case Command::WRA:
phase = BEGIN_WRA;
break;
case Command::REFA:
if (!Configuration::getInstance().BankwiseLogic)
phase = BEGIN_REFA;
else
phase = BEGIN_REFB;
break;
case Command::ACT:
phase = BEGIN_ACT;
break;
case Command::ACTB:
phase = BEGIN_ACTB;
break;
case Command::PRE:
phase = BEGIN_PRE;
break;
case Command::PREB:
phase = BEGIN_PREB;
break;
case Command::PREA:
phase = BEGIN_PRE_ALL;
break;
case Command::PDEA:
if (!Configuration::getInstance().BankwiseLogic)
phase = BEGIN_PDNA;
else
phase = BEGIN_PDNAB;
break;
case Command::PDXA:
if (!Configuration::getInstance().BankwiseLogic)
phase = END_PDNA;
else
phase = END_PDNAB;
break;
case Command::PDEP:
if (!Configuration::getInstance().BankwiseLogic)
phase = BEGIN_PDNP;
else
phase = BEGIN_PDNPB;
break;
case Command::PDXP:
if (!Configuration::getInstance().BankwiseLogic)
phase = END_PDNP;
else
phase = END_PDNPB;
break;
case Command::SREFEN:
if (!Configuration::getInstance().BankwiseLogic)
phase = BEGIN_SREF;
else
phase = BEGIN_SREFB;
break;
case Command::SREFEX:
if (!Configuration::getInstance().BankwiseLogic)
phase = END_SREF;
else
phase = END_SREFB;
break;
default:
SC_REPORT_FATAL(0, "unsupported command was sent by controller");
break;
}
sc_time notDelay = command.getStart() - sc_time_stamp();
printDebugMessage(phaseNameToString(phase) + " notification in " +
notDelay.to_string());
controllerCorePEQ.notify(payload, phase, notDelay);
}
//Trigger the next planned refresh or the power down mode on the DRAM
void Controller::send(Trigger trigger, sc_time time,
tlm_generic_payload &payload)
{
sc_assert(time >= sc_time_stamp());
tlm_phase phase;
if (trigger == Trigger::REFTrigger) {
phase = REF_TRIGGER;
} else if (trigger == Trigger::PDNTrigger) {
phase = PDN_TRIGGER;
} else {
SC_REPORT_FATAL("controller wrapper", "unknown trigger");
}
sc_time delay = time - sc_time_stamp();
printDebugMessage(phaseNameToString(phase) + " notification in " +
delay.to_string());
controllerCorePEQ.notify(payload, phase, delay);
}
void Controller::controllerCorePEQCallback(tlm_generic_payload &payload,
const tlm_phase &phase)
{
if (phase == REF_TRIGGER)
{
//controllerCore->triggerRefresh(payload);
}
else if (phase == PDN_TRIGGER)
{
//controllerCore->powerDownManager->sleep(DramExtension::getExtension(
// payload).getBank(), sc_time_stamp());
}
else
{
Bank bank = DramExtension::getBank(payload);
sendToDram(payload, phase, SC_ZERO_TIME);
if (phase == BEGIN_RD || phase == BEGIN_WR)
scheduleNextFromScheduler(DramExtension::getBank(payload));
else if (phase == BEGIN_REFB)
printDebugMessage("Entering REFB on bank " + to_string(bank.ID()));
else if (phase == BEGIN_REFA)
printDebugMessage("Entering REFA");
else if (containsPhase(phase, { BEGIN_PDNAB, BEGIN_PDNPB, BEGIN_SREFB }))
printDebugMessage("Entering PowerDown " + phaseNameToString(
phase) + " on bank " + to_string(bank.ID()));
else if (containsPhase(phase, { END_PDNAB, END_PDNPB, END_SREFB }))
printDebugMessage("Leaving PowerDown " + phaseNameToString(
phase) + " on bank " + to_string(bank.ID()));
else if (containsPhase(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF }))
printDebugMessage("Entering PowerDown " + phaseNameToString(
phase) + " on all banks");
else if (containsPhase(phase, { END_PDNA, END_PDNP, END_SREF }))
printDebugMessage("Leaving PowerDown " + phaseNameToString(
phase) + " on all banks" );
else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACTB, BEGIN_ACT, BEGIN_PREB, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) {
printDebugMessage("Controller has sent to DRAM this: " + phaseNameToString(
phase) + " bank " + to_string(bank.ID()));
}
else
SC_REPORT_FATAL(0,
"Controller Core PEQ in controller wrapper was triggered with unsupported phase");
}
}
tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &fwDelay)
{
sc_time notDelay = fwDelay;
if (phase == BEGIN_REQ)
{
notDelay += Configuration::getInstance().memSpec->clk;
// Bandwidth IDLE
if ((getTotalNumberOfPayloadsInSystem() == 0) && idleState)
endBandwidthIdleCollector();
}
else if (phase == END_RESP)
{
// Bandwidth IDLE
if (getTotalNumberOfPayloadsInSystem() == 1)
startBandwidthIdleCollector();
}
printDebugMessage("[fw] " + phaseNameToString(phase) + " notification in " +
notDelay.to_string());
frontendPEQ.notify(payload, phase, notDelay);
return TLM_ACCEPTED;
}
unsigned int Controller::transport_dbg(tlm::tlm_generic_payload &trans)
{
return iSocket->transport_dbg(trans);
}
void Controller::frontendPEQCallback(tlm_generic_payload &payload,
const tlm_phase &phase)
{
if (phase == BEGIN_REQ)
{
printDebugMessage(string("Payloads in system: ") +
to_string(getTotalNumberOfPayloadsInSystem()));
payload.acquire();
payloadEntersSystem(payload);
if (getTotalNumberOfPayloadsInSystem() >
controllerCore->config.MaxNrOfTransactions)
{
printDebugMessage("##Backpressure: Max number of transactions in system reached");
backpressure = &payload;
}
else
{
payload.set_response_status(tlm::TLM_OK_RESPONSE);
sendToFrontend(payload, END_REQ, SC_ZERO_TIME);
scheduler->storeRequest(&payload);
// TODO: remove this
scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank());
}
}
else if (phase == PendingRequest)
{
// Schedule a pending request.
scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank());
}
else if (phase == END_RESP)
{
if (backpressure != NULL)
{
printDebugMessage("##Backpressure released");
backpressure->set_response_status(tlm::TLM_OK_RESPONSE);
sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME);
scheduler->storeRequest(backpressure);
scheduleNextFromScheduler(DramExtension::getExtension(backpressure).getBank());
backpressure = NULL;
}
payloadLeavesSystem(payload);
responseQueue.pop();
payload.release();
if(!responseQueue.empty())
sendToFrontend(*(responseQueue.front()), BEGIN_RESP, SC_ZERO_TIME);
}
else
{
SC_REPORT_FATAL(0,
"Front-end PEQ in controller wrapper was triggered with unknown phase");
}
}
void Controller::payloadEntersSystem(tlm_generic_payload &payload)
{
Bank bank = DramExtension::getExtension(payload).getBank();
numberOfPayloadsInSystem[bank]++;
printDebugMessage(
"Payload enters system on bank " + to_string(bank.ID()) +
". Total number of payloads in Controller: "
+ to_string(getTotalNumberOfPayloadsInSystem()));
// Set Start Time for Simulation
if (!startTimeSet)
{
printDebugMessage("Simulation Timer Start");
startTime = sc_time_stamp() - Configuration::getInstance().memSpec->clk;
startTimeSet = true;
}
}
void Controller::payloadLeavesSystem(tlm_generic_payload &payload)
{
Bank bank = DramExtension::getExtension(payload).getBank();
numberOfPayloadsInSystem[bank]--;
printDebugMessage(
"Payload left system on bank " + to_string(bank.ID()) +
". Total number of payloads in Controller: "
+ to_string(getTotalNumberOfPayloadsInSystem()));
//controllerCore->powerDownManager->triggerSleep(bank, sc_time_stamp());
}
unsigned int Controller::getTotalNumberOfPayloadsInSystem()
{
unsigned int sum = 0;
for (Bank bank : controllerCore->getBanks())
sum += numberOfPayloadsInSystem[bank];
return sum;
}
void Controller::scheduleNextFromScheduler(Bank bank)
{
if (controllerCore->bankIsBusy(bank))
return;
// TODO: rescheduled always true?
bool rescheduled = true;
pair<Command, tlm::tlm_generic_payload *> nextRequest =
scheduler->getNextRequest(bank);
if (nextRequest.second != NULL)
{
schedule(nextRequest.first, *nextRequest.second);
}
else
{
gp *pendingRequest = scheduler->getPendingRequest(bank);
// TODO: if path (pendingRequest != NULL) is only used by SMS scheduler
if (pendingRequest != NULL)
{
rescheduled = true;
frontendPEQ.notify(*(pendingRequest), PendingRequest,
Configuration::getInstance().memSpec->clk);
}
}
// TODO: only used with FifoStrict scheduler
queue<Bank> blocked;
while (!blockedRequests.empty())
{
bank = blockedRequests.front();
blockedRequests.pop();
pair<Command, tlm::tlm_generic_payload *> nextRequest =
scheduler->getNextRequest(bank);
if (nextRequest.second != NULL)
{
schedule(nextRequest.first, *nextRequest.second);
}
else
{
gp *pendingRequest = scheduler->getPendingRequest(bank);
if (pendingRequest != NULL)
{
//Pending request
if (!rescheduled)
{
// TODO: never reached, rescheduled is always true
rescheduled = true;
frontendPEQ.notify(*(pendingRequest), PendingRequest,
Configuration::getInstance().memSpec->clk);
}
else
{
blocked.push(bank);
}
}
}
}
blockedRequests = blocked;
}
void Controller::schedule(Command command, gp &payload)
{
//controllerCore->powerDownManager->wakeUp(DramExtension::getBank(payload),
// sc_time_stamp());
if (controllerCore->scheduleRequest(command, payload))
{
printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(
command) + "] (unblocked)");
}
}
void Controller::sendToFrontend(tlm_generic_payload &payload,
const tlm_phase &phase, const sc_time &delay)
{
tlm_phase TPhase = phase;
sc_time TDelay = delay;
tSocket->nb_transport_bw(payload, TPhase, TDelay);
}
tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &bwDelay)
{
printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " +
bwDelay.to_string());
dramPEQ.notify(payload, phase, bwDelay);
return TLM_ACCEPTED;
}
void Controller::dramPEQCallback(tlm_generic_payload &payload,
const tlm_phase &phase)
{
Bank bank = DramExtension::getExtension(payload).getBank();
printDebugMessage("Received " + phaseNameToString(phase) + " on bank " +
to_string(bank.ID()) + " from DRAM");
if (phase == END_RD || phase == END_WR)
{
if(responseQueue.empty())
sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME);
responseQueue.push(&payload);
}
else if (phase == END_RDA || phase == END_WRA)
{
if(responseQueue.empty())
sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME);
responseQueue.push(&payload);
scheduleNextFromScheduler(bank);
}
else if (phase == END_REFA)
{
printDebugMessage("Finished auto refresh on all banks ");
bool sleepy = true;
for (Bank bank : controllerCore->getBanks())
{
if (numberOfPayloadsInSystem[bank] != 0)
{
sleepy = false;
scheduleNextFromScheduler(bank);
}
}
//if (sleepy == true)
//controllerCore->powerDownManager->sleep(0, sc_time_stamp());
}
else if (phase == END_REFB)
{
printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID()));
if (numberOfPayloadsInSystem[bank] == 0) {}
//controllerCore->powerDownManager->sleep(bank, sc_time_stamp());
else
scheduleNextFromScheduler(bank);
scheduleNextFromScheduler(bank);
}
else if (containsPhase(phase, {END_PREB, END_PRE, END_ACTB, END_ACT}))
{
scheduleNextFromScheduler(bank);
}
else if (phase == END_PRE_ALL)
{
// No need to trigger anything for a END_PRE_ALL. It is followed by a AUTO_REFRESH anyway (in our current
// scheduler implementation)
}
else
{
string str =
string("DRAM PEQ in controller wrapper was triggered with unsupported phase ")
+ phaseNameToString(phase);
SC_REPORT_FATAL(0, str.c_str());
}
}
void Controller::sendToDram(tlm_generic_payload &payload,
const tlm_phase &phase, const sc_time &delay)
{
tlm_phase TPhase = phase;
sc_time TDelay = delay;
if (phase == BEGIN_WR || phase == BEGIN_RD || phase == BEGIN_WRA || phase == BEGIN_RDA)
numberOfTransactionsServed++;
iSocket->nb_transport_fw(payload, TPhase, TDelay);
}
void Controller::printDebugMessage(string message)
{
debugManager.printDebugMessage(name(), message);
}
bool Controller::containsPhase(tlm_phase phase, std::vector<tlm_phase> phases)
{
for (tlm_phase p : phases) {
if (p == phase)
return true;
}
return false;
}
void Controller::end_of_simulation()
{
terminateSimulation();
}
void Controller::terminateSimulation()
{
if (Configuration::getInstance().BankwiseLogic) {
for (Bank bank : controllerCore->getBanks()) {
//controllerCore->powerDownManager->wakeUp(bank, clkAlign(sc_time_stamp()));
}
} else {
//controllerCore->powerDownManager->wakeUp(0, clkAlign(sc_time_stamp()));
}
endTime = sc_time_stamp();
}
void Controller::startBandwidthIdleCollector()
{
printDebugMessage("IDLE Start");
idleStart = sc_time_stamp();
endTime = sc_time_stamp();
idleState = true;
}
void Controller::endBandwidthIdleCollector()
{
printDebugMessage("IDLE End");
idleTime += sc_time_stamp() - idleStart +
Configuration::getInstance().memSpec->clk;
idleState = false;
}
sc_time Controller::getIdleTime()
{
printDebugMessage("IDLE Time: " + idleTime.to_string());
return idleTime;
}
sc_time Controller::getEndTime()
{
printDebugMessage("End Time: " + endTime.to_string());
return endTime;
}
sc_time Controller::getStartTime()
{
printDebugMessage("Start Time: " + startTime.to_string());
return startTime;
}

View File

@@ -1,169 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
* Eder F. Zulian
*/
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <systemc>
#include <tlm>
#include <tlm_utils/peq_with_cb_and_phase.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include "../common/dramExtensions.h"
#include "../common/DebugManager.h"
#include "../common/protocol.h"
#include "../common/TlmRecorder.h"
#include "../common/utils.h"
#include "core/configuration/Configuration.h"
#include "core/configuration/MemSpec.h"
#include "Command.h"
#include "core/ControllerCore.h"
#include "ControllerState.h"
#include "IController.h"
#include "core/powerdown/IPowerDownManager.h"
#include "core/scheduling/ScheduledCommand.h"
#include "core/timingCalculations.h"
#include "scheduler/Fifo.h"
#include "scheduler/Grp.h"
#include "scheduler/FifoStrict.h"
#include "scheduler/FrFcfs.h"
#include "scheduler/FrFcfsRp.h"
#include "scheduler/FrFcfsGrp.h"
#include "scheduler/SMS.h"
#include "scheduler/IScheduler.h"
#include "GenericController.h"
using namespace std;
using namespace tlm;
DECLARE_EXTENDED_PHASE(PendingRequest);
class Controller : public GenericController, public IController
{
public:
Controller(sc_module_name);
virtual ~Controller();
void terminateSimulation();
sc_time getIdleTime();
sc_time getEndTime();
sc_time getStartTime();
// ------- CONTROLLER CORE ---------
virtual void send(const ScheduledCommand &command,
tlm_generic_payload &payload) override;
virtual void send(Trigger trigger, sc_time time,
tlm_generic_payload &payload) override;
unsigned int getTotalNumberOfPayloadsInSystem();
void scheduleNextFromScheduler(Bank bank) override;
static unsigned int ControllerThreadId()
{
return controllerThreadId;
}
protected:
void buildScheduler();
void payloadEntersSystem(tlm_generic_payload &payload);
void payloadLeavesSystem(tlm_generic_payload &payload);
// --- FRONTEND ------
virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &fwDelay);
virtual unsigned int transport_dbg(tlm::tlm_generic_payload &trans);
void frontendPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase);
virtual void sendToFrontend(tlm_generic_payload &payload,
const tlm_phase &phase, const sc_time &delay);
// --- DRAM ------
virtual tlm_sync_enum nb_transport_bw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &bwDelay);
void dramPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase);
void sendToDram(tlm_generic_payload &payload, const tlm_phase &phase,
const sc_time &delay);
// ------- CONTROLLER CORE ---------
virtual void schedule(Command command, gp &payload);
void controllerCorePEQCallback(tlm_generic_payload &payload,
const tlm_phase &phase);
// Helpers TODO move them
void printDebugMessage(string message);
bool containsPhase(tlm_phase phase, std::vector<tlm_phase> phases);
ControllerCore *controllerCore;
//Scheduler* scheduler;
IScheduler *scheduler;
std::map<Bank, int> numberOfPayloadsInSystem;
std::vector<gp *> refreshCollisionRequets;
tlm_generic_payload *backpressure = NULL;
std::queue<gp *> responseQueue;
tlm_utils::peq_with_cb_and_phase<Controller> frontendPEQ;
tlm_utils::peq_with_cb_and_phase<Controller> dramPEQ;
tlm_utils::peq_with_cb_and_phase<Controller> controllerCorePEQ;
DebugManager &debugManager;
// Bandwidth realted:
sc_time idleStart;
bool idleState = false;
sc_time idleTime;
sc_time endTime;
sc_time startTime;
bool startTimeSet = false;
unsigned long long int numberOfTransactionsServed = 0;
void startBandwidthIdleCollector();
void endBandwidthIdleCollector();
// SystemC related:
virtual void end_of_simulation() override;
static const unsigned int controllerThreadId = INT_MAX;
};
#endif // CONTROLLER_H

View File

@@ -1,107 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
* Felipe S. Prado
*/
#include "ControllerState.h"
#include <algorithm>
#include "core/timingCalculations.h"
using namespace std;
const ScheduledCommand ControllerState::getLastCommandOnBank(Command command,
Bank bank) //TODO const reference? and make const
{
return lastScheduledByCommandAndBank[command][bank];
}
const ScheduledCommand ControllerState::getLastCommand(Command command)
{
return lastScheduledByCommand[command];
}
const ScheduledCommand ControllerState::getLastScheduledCommand()
{
return lastScheduled;
}
const ScheduledCommand ControllerState::getLastScheduledCommand(Bank bank)
{
ScheduledCommand lastCommand;
for (Command cmd : getAllCommands()) {
ScheduledCommand &current = lastScheduledByCommandAndBank[cmd][bank];
if (current.getStart() > lastCommand.getStart())
lastCommand = current;
}
printDebugMessage("Last scheduled command on bank " + to_string(
bank.ID()) + " was " + commandToString(lastCommand.getCommand()));
return lastCommand;
}
void ControllerState::change(const ScheduledCommand &scheduledCommand)
{
Command command = scheduledCommand.getCommand();
printDebugMessage("Changing state on bank " + to_string(
scheduledCommand.getBank().ID()) + " command is " + commandToString(
command));
//bus.blockSlot(scheduledCommand.getStart());
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());
}
}
void ControllerState::cleanUp(sc_time time)
{
bus.cleanUpSlots(time);
}
void ControllerState::printDebugMessage(std::string message)
{
DebugManager::getInstance().printDebugMessage(ownerName, message);
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#ifndef CONTROLLERSTATE_H
#define CONTROLLERSTATE_H
#include <systemc.h>
#include "core/Slots.h"
#include "core/configuration/Configuration.h"
#include <map>
#include <queue>
#include <set>
#include <list>
class ControllerState
{
public:
ControllerState(std::string ownerName, Configuration *config)
: bus(config->memSpec->clk), ownerName(ownerName),
config(config) {}
const ScheduledCommand getLastCommandOnBank(Command command, Bank bank);
const ScheduledCommand getLastCommand(Command command);
const ScheduledCommand getLastScheduledCommand(Bank bank);
const ScheduledCommand getLastScheduledCommand();
void change(const ScheduledCommand &scheduledCommand);
void cleanUp(sc_time time);
//used by the various checkers
std::map<Command, std::map<Bank, ScheduledCommand>> lastScheduledByCommandAndBank;
// TODO: remove
std::map<Command, ScheduledCommand> lastScheduledByCommand;
//std::map<Bank, ScheduledCommand> lastScheduledByBank;
ScheduledCommand lastScheduled;
Slots bus;
std::queue<sc_time> lastActivates;
std::map<sc_time, ScheduledCommand> lastActivatesB;
private:
std::string ownerName;
Configuration *config;
void printDebugMessage(std::string message);
};
#endif // CONTROLLERSTATE_H

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef ICONTROLLER_H
#define ICONTROLLER_H
#include <queue>
#include <systemc.h>
#include "core/scheduling/ScheduledCommand.h"
#include "../common/dramExtensions.h"
enum Trigger {REFTrigger, PDNTrigger};
// Utiliy class to pass around the Controller class to the controller Core and various schedulers, without having to propagate the template defintions
// throughout all classes
class IController
{
public:
virtual ~IController() {}
virtual void send(const ScheduledCommand &command,
tlm::tlm_generic_payload &payload) = 0;
virtual void send(Trigger trigger, sc_time time,
tlm::tlm_generic_payload &payload) = 0;
virtual void scheduleNextFromScheduler(Bank bank) = 0;
std::queue<Bank> blockedRequests;
};
#endif // ICONTROLLER_H

View File

@@ -1,92 +0,0 @@
/*
* Copyright (c) 2018, 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.
*
* Authors:
* Felipe S. Prado
* Matthias Jung
*/
#include "RecordableController.h"
tlm_sync_enum RecordableController::nb_transport_fw(tlm_generic_payload
&payload, tlm_phase &phase, sc_time &fwDelay)
{
recordPhase(payload, phase, fwDelay);
return Controller::nb_transport_fw(payload, phase, fwDelay);
}
void RecordableController::sendToFrontend(tlm_generic_payload &payload,
const tlm_phase &phase, const sc_time &delay)
{
recordPhase(payload, phase, delay);
Controller::sendToFrontend(payload, phase, delay);
}
tlm_sync_enum RecordableController::nb_transport_bw(tlm_generic_payload
&payload, tlm_phase &phase, sc_time &bwDelay)
{
recordPhase(payload, phase, bwDelay);
return Controller::nb_transport_bw(payload, phase, bwDelay);
}
void RecordableController::recordPhase(tlm::tlm_generic_payload &trans,
tlm::tlm_phase phase, sc_time delay)
{
sc_time recTime = delay + sc_time_stamp();
unsigned int thr = DramExtension::getExtension(trans).getThread().ID();
unsigned int ch = DramExtension::getExtension(trans).getChannel().ID();
unsigned int bg = DramExtension::getExtension(trans).getBankGroup().ID();
unsigned int bank = DramExtension::getExtension(trans).getBank().ID();
unsigned int row = DramExtension::getExtension(trans).getRow().ID();
unsigned int col = DramExtension::getExtension(trans).getColumn().ID();
printDebugMessage("Recording " + phaseNameToString(phase) + " thread " +
to_string(thr) + " channel " + to_string(ch) + " bank group " + to_string(
bg) + " bank " + to_string(bank) + " row " + to_string(row) + " column " +
to_string(col) + " at " + recTime.to_string());
tlmRecorder->recordPhase(trans, phase, recTime);
}
void RecordableController::schedule(Command command, gp &payload)
{
Controller::schedule(command, payload);
if (commandIsIn(command, {Command::RD, Command::RDA, Command::WR, Command::WRA})) {
ScheduledCommand scheduledCommand = controllerCore->state->getLastCommandOnBank(
command, DramExtension::getBank(payload));
TimeInterval dataStrobe = scheduledCommand.getIntervalOnDataStrobe();
tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
}
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2018, 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.
*
* Authors:
* Felipe S. Prado
* Matthias Jung
*/
#ifndef RECORDABLECONTROLLER_H
#define RECORDABLECONTROLLER_H
#include "Controller.h"
struct RecordableController: public Controller {
public:
RecordableController(sc_module_name name, TlmRecorder *rec) :
Controller(name), tlmRecorder(rec)
{
}
protected:
TlmRecorder *tlmRecorder;
virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &fwDelay) override;
virtual tlm_sync_enum nb_transport_bw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &bwDelay) override;
virtual void sendToFrontend(tlm_generic_payload &payload,
const tlm_phase &phase, const sc_time &delay) override;
virtual void schedule(Command command, tlm_generic_payload &payload) override;
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase,
sc_time delay);
};
#endif // RECORDABLECONTROLLER_H

View File

@@ -1,99 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
*/
#include "RowBufferStates.h"
#include "core/ControllerCore.h"
#include "../common/DebugManager.h"
#include "../common/utils.h"
using namespace std;
RowBufferState::RowBufferState(std::string ownerName) : ownerName(ownerName)
{
closeAllRowBuffers();
}
RowBufferState::~RowBufferState()
{
}
bool RowBufferState::rowBufferIsOpen(Bank bank) const
{
return getElementFromMap(rowsInRowBuffers, bank) != Row::NO_ROW;
}
Row RowBufferState::getRowInRowBuffer(Bank bank) const
{
return getElementFromMap(rowsInRowBuffers, bank);
}
void RowBufferState::openRowInRowBuffer(Bank bank, Row row)
{
printDebugMessage("Row buffer for bank " + to_string(bank.ID()) +
" is now open");
rowsInRowBuffers[bank] = row;
}
void RowBufferState::closeRowBuffer(Bank bank)
{
printDebugMessage("Row buffer for bank " + to_string(bank.ID()) +
" is now closed");
rowsInRowBuffers[bank] = Row::NO_ROW;
}
bool RowBufferState::allRowBuffersAreClosed() const
{
for (unsigned int i = 0; i < Configuration::getInstance().memSpec->NumberOfBanks;
++i) {
if (rowBufferIsOpen(Bank(i)))
return false;
}
return true;
}
void RowBufferState::closeAllRowBuffers()
{
for (unsigned int i = 0; i < Configuration::getInstance().memSpec->NumberOfBanks;
++i) {
rowsInRowBuffers[Bank(i)] = Row::NO_ROW;
}
}
void RowBufferState::printDebugMessage(std::string message)
{
DebugManager::getInstance().printDebugMessage(ownerName, message);
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
*/
#ifndef ROWBUFFERSTATES_H
#define ROWBUFFERSTATES_H
#include <map>
#include "../common/dramExtensions.h"
class RowBufferState
{
public:
RowBufferState(std::string ownerName);
virtual ~RowBufferState();
bool rowBufferIsOpen(Bank bank) const;
bool allRowBuffersAreClosed() const;
Row getRowInRowBuffer(Bank bank) const;
void openRowInRowBuffer(Bank bank, Row row);
void closeRowBuffer(Bank bank);
void closeAllRowBuffers();
private:
std::string ownerName;
std::map<Bank, Row> rowsInRowBuffers;
void printDebugMessage(std::string message);
};
#endif // ROWBUFFERSTATES_H

View File

@@ -1,284 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
* Felipe S. Prado
*/
#include <systemc.h>
#include "ControllerCore.h"
#include "scheduling/checker/ActBChecker.h"
#include "scheduling/checker/ActivateChecker.h"
#include "scheduling/checker/PreBChecker.h"
#include "scheduling/checker/PrechargeChecker.h"
#include "scheduling/checker/PrechargeAllChecker.h"
#include "scheduling/checker/ReadChecker.h"
#include "scheduling/checker/WriteChecker.h"
#include "scheduling/checker/RefreshChecker.h"
#include "scheduling/checker/PowerDownChecker.h"
#include "refresh/RefreshManagerBankwise.h"
#include "refresh/RefreshManager.h"
#include "refresh/RGR.h"
#include "../../common/dramExtensions.h"
#include "../../common/utils.h"
#include "timingCalculations.h"
#include "scheduling/checker/CheckerDDR3New.h"
#include "powerdown/PowerDownManager.h"
#include "powerdown/PowerDownManagerTimeout.h"
#include "powerdown/PowerDownManagerBankwise.h"
#include "powerdown/PowerDownManagerTimeoutBankwise.h"
#include "powerdown/NoPowerDown.h"
#include "../../common/DebugManager.h"
ControllerCore::ControllerCore(sc_module_name /*name*/,
IController &wrapperConnector, std::map<Bank, int> &numberOfPayloads) :
config(Configuration::getInstance()), controller(wrapperConnector),
numberOfPayloads(numberOfPayloads), commandChecker()
{
state = new ControllerState(name(), &config);
commandChecker[Command::ACTB] = new ActBChecker(config, *state);
commandChecker[Command::ACT] = new ActivateChecker(config, *state);
commandChecker[Command::PREB] = new PreBChecker(config, *state);
commandChecker[Command::PRE] = new PrechargeChecker(config, *state);
commandChecker[Command::PREA] = new PrechargeAllChecker(config, *state);
commandChecker[Command::RD] = new ReadChecker(config, *state);
commandChecker[Command::RDA] = commandChecker[Command::RD];
commandChecker[Command::WR] = new WriteChecker(config, *state);
commandChecker[Command::WRA] = commandChecker[Command::WR];
commandChecker[Command::REFA] = new RefreshChecker(config, *state);
commandChecker[Command::PDEA] = new PowerDownChecker(config, *state);
commandChecker[Command::PDEP] = commandChecker[Command::PDEA];
commandChecker[Command::SREFEN] = commandChecker[Command::PDEA];
commandChecker[Command::PDXA] = commandChecker[Command::PDEA];
commandChecker[Command::PDXP] = commandChecker[Command::PDEA];
commandChecker[Command::SREFEX] = commandChecker[Command::PDEA];
//timingChecker = new CheckerDDR3New(config, *state);
// if (config.RowGranularRef) {
// refreshManager = new RGR("RGR", *this);
// } else {
// if (config.BankwiseLogic) {
// refreshManager = new RefreshManagerBankwise("refManagerBw", *this);
// } else {
// refreshManager = new RefreshManager("refManager", *this);
// }
// }
// if (config.PowerDownMode == EPowerDownMode::Staggered) {
// if (config.BankwiseLogic)
// powerDownManager = new PowerDownManagerBankwise("pdnManagerBw", *this);
// else
// powerDownManager = new PowerDownManager("pdnManager", *this);
// } else if (config.PowerDownMode == EPowerDownMode::TimeoutPDN
// || config.PowerDownMode == EPowerDownMode::TimeoutSREF) {
// if (config.BankwiseLogic)
// powerDownManager = new PowerDownManagerTimeoutBankwise("pdnManagerBw", *this);
// else
// powerDownManager = new PowerDownManagerTimeout("pdnManager", *this);
// } else if (config.PowerDownMode == EPowerDownMode::NoPowerDown) {
// powerDownManager = new NoPowerDown();
// } else {
// SC_REPORT_FATAL(0,
// "Unsupported powerdown mode in constructor of controller core");
// }
}
ControllerCore::~ControllerCore()
{
delete commandChecker[Command::ACT];
delete commandChecker[Command::PRE];
delete commandChecker[Command::PREA];
delete commandChecker[Command::RD];
delete commandChecker[Command::WR];
delete commandChecker[Command::REFA];
delete commandChecker[Command::PDEA];
//delete timingChecker;
//delete refreshManager;
//delete powerDownManager;
delete state;
}
//void ControllerCore::triggerRefresh(tlm::tlm_generic_payload &payload)
//{
// /* Refresh can be disabled for tests purpose */
// if (config.ControllerCoreRefDisable == false)
// {
// sc_time time = sc_time_stamp();
// Bank bank = DramExtension::getExtension(payload).getBank();
// state->cleanUp(time);
// if (!refreshManager->isInvalidated(payload, time)
// && !powerDownManager->isInSelfRefresh(bank))
// {
// printDebugMessage("Triggering refresh on bank " + to_string(bank.ID()));
// powerDownManager->wakeUpForRefresh(bank,
// time); //expects PDNA and PDNP to exit without delay
// bool pdnpToSrefTransition = false;
// if (config.PowerDownMode == EPowerDownMode::Staggered)
// pdnpToSrefTransition = (state->getLastCommand(Command::PDXP,
// bank).getStart() >= time);
// if (pdnpToSrefTransition)
// powerDownManager->sleep(bank, time);
// else
// refreshManager->scheduleRefresh(payload, time);
// }
// }
//}
bool ControllerCore::scheduleRequest(Command command,
tlm::tlm_generic_payload &payload)
{
sc_time start = clkAlign(sc_time_stamp());
state->cleanUp(start);
ScheduledCommand scheduledCommand = schedule(command, start, payload);
//if (config.ControllerCoreRefDisable)
//{
state->change(scheduledCommand);
controller.send(scheduledCommand, payload);
return true;
// }
// else
// {
// if (!((command == Command::PRE || command == Command::ACT)
// && refreshManager->hasCollision(scheduledCommand)))
// {
// state->change(scheduledCommand);
// controller.send(scheduledCommand, payload);
// return true;
// }
// }
// return false;
}
ScheduledCommand ControllerCore::schedule(Command command, sc_time start,
tlm::tlm_generic_payload &payload)
{
ControllerCore::printDebugMessage("Scheduling command " + commandToString(
command) + " on " + DramExtension::getBank(payload).toString());
sc_time executionTime = Configuration::getInstance().memSpec->getExecutionTime(command, payload);
ScheduledCommand scheduledCommand(command, start, executionTime,
DramExtension::getExtension(payload));
getCommandChecker(command).delayToSatisfyConstraints(scheduledCommand);
return scheduledCommand;
}
bool ControllerCore::hasPendingRequests()
{
for (Bank bank : getBanks())
{
if (numberOfPayloads[bank] != 0)
return true;
}
return false;
}
bool ControllerCore::hasPendingRequests(Bank bank)
{
return (numberOfPayloads[bank] != 0) ? true : false;
}
bool ControllerCore::bankIsBusy(Bank bank)
{
sc_time time = sc_time_stamp();
ScheduledCommand lastScheduledCommand = state->getLastScheduledCommand(bank);
if (lastScheduledCommand.isNoCommand())
{
return false;
}
else if (lastScheduledCommand.commandIsIn({Command::WR, Command::RD}))
{
// Read and writes can overlap, so the bank should not be busy during a rd/wr
return (time < lastScheduledCommand.getStart());
}
else if (lastScheduledCommand.commandIsIn({Command::WRA, Command::RDA, Command::PREB,
Command::PRE, Command::PREA,
Command::ACTB, Command::ACT}))
{
return (time < lastScheduledCommand.getEnd());
}
else if (lastScheduledCommand.getCommand() == Command::REFA)
{
return (time < lastScheduledCommand.getEnd());
}
else if (lastScheduledCommand.commandIsIn({Command::SREFEX, Command::PDXP, Command::PDXA,
Command::SREFEN, Command::PDEP, Command::PDEA}))
{
return false;
}
else
{
SC_REPORT_FATAL("Core", "Last command unkown");
return false;
}
}
const std::vector<Bank> &ControllerCore::getBanks()
{
static std::vector<Bank> banks;
if (banks.size() == 0) {
for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; i++) {
banks.push_back(Bank(i));
}
}
return banks;
}
std::vector<Bank> ControllerCore::getFreeBanks()
{
std::vector<Bank> freeBanks;
for (Bank bank : getBanks()) {
if (!bankIsBusy(bank))
freeBanks.push_back(bank);
}
return freeBanks;
}
ICommandChecker &ControllerCore::getCommandChecker(Command command)
{
return *getElementFromMap(commandChecker, command);
//return *timingChecker;
}
void ControllerCore::printDebugMessage(string message)
{
DebugManager::getInstance().printDebugMessage(this->name(), message);
}

View File

@@ -1,90 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#ifndef CONTROLLERCORE_H
#define CONTROLLERCORE_H
#include <tlm.h>
#include <map>
#include <utility>
#include <string>
#include "../IController.h"
#include "configuration/Configuration.h"
#include "powerdown/PowerDownManager.h"
#include "refresh/IRefreshManager.h"
#include "scheduling/checker/ICommandChecker.h"
//#include "../RowBufferStates.h"
#include "../ControllerState.h"
using namespace std;
class ControllerCore : public sc_module
{
public:
ControllerCore(sc_module_name /*name*/, IController &controller,
std::map<Bank, int> &numberOfPayloads);
virtual ~ControllerCore();
bool scheduleRequest(Command command, tlm::tlm_generic_payload &payload);
//void triggerRefresh(tlm::tlm_generic_payload &payload);
const std::vector<Bank> &getBanks();
std::vector<Bank> getFreeBanks();
bool hasPendingRequests();
bool hasPendingRequests(Bank bank);
bool bankIsBusy(Bank bank);
ICommandChecker &getCommandChecker(Command command);
Configuration config;
ControllerState *state;
IController &controller;
//IPowerDownManager *powerDownManager;
//IRefreshManager *refreshManager;
std::map<Bank, int> &numberOfPayloads;
private:
ScheduledCommand schedule(Command command, sc_time start,
tlm::tlm_generic_payload &payload);
std::map<Command, ICommandChecker *> commandChecker;
//ICommandChecker *timingChecker;
void printDebugMessage(string message);
};
#endif // CONTROLLERCORE_H

View File

@@ -1,87 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
*/
#include "Slots.h"
#include "timingCalculations.h"
Slots::Slots(sc_time clk) :
clk(clk)
{
}
Slots::~Slots()
{
}
void Slots::moveCommandToNextFreeSlot(ScheduledCommand &command)
{
while (!isFree(command.getStart()))
command.delayStart(clk);
}
void Slots::cleanUpSlots(sc_time time)
{
slotSet.erase(slotSet.begin(), slotSet.lower_bound(time));
}
void Slots::blockSlot(sc_time time)
{
sc_assert(isClkAligned(time, clk));
slotSet.insert(time);
}
bool Slots::isFree(sc_time time)
{
return (slotSet.count(time) == 0);
}
void Slots::blockSlots(sc_time begin, sc_time end, bool excludeBorders)
{
sc_assert(isClkAligned(begin, clk));
sc_assert(isClkAligned(end, clk));
if (excludeBorders) {
begin += clk;
end -= clk;
}
for (sc_time time = begin; time <= end; time += clk) {
blockSlot(time);
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
*/
#ifndef SLOTS_H
#define SLOTS_H
#include <systemc.h>
#include <set>
#include "scheduling/ScheduledCommand.h"
class Slots
{
public:
Slots(sc_time clk);
virtual ~Slots();
void moveCommandToNextFreeSlot(ScheduledCommand &command);
void cleanUpSlots(sc_time time);
void blockSlot(sc_time time);
bool isFree(sc_time);
private:
sc_time clk;
std::set<sc_time> slotSet;
void blockSlots(sc_time begin, sc_time end, bool excludeBorders);
};
#endif // SLOTS_H

View File

@@ -1,66 +0,0 @@
///*
// * Copyright (c) 2015, 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.
// *
// * Authors:
// * Janik Schlemminger
// * Robert Gernhardt
// * Matthias Jung
// */
//#ifndef IREFRESHMANAGER_H
//#define IREFRESHMANAGER_H
//#include <systemc.h>
//#include "../scheduling/ScheduledCommand.h"
//// Flex. refresh (pull-in, postpone)
//typedef enum {
// ST_REFRESH = 0,
// ST_PULLIN,
// ST_POSTPONE,
// ST_SKIP,
// ST_BURST,
// ST_ALIGN
//} ref_fsm_state_t;
//class IRefreshManager
//{
//public:
// virtual ~IRefreshManager() {};
// virtual bool hasCollision(const ScheduledCommand &command) = 0;
// virtual void scheduleRefresh(tlm::tlm_generic_payload &payload,
// sc_time time) = 0;
// virtual void reInitialize(Bank bank, sc_time time) = 0;
// virtual bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) = 0;
//};
//#endif // IREFRESHMANAGER_H

View File

@@ -1,275 +0,0 @@
///*
// * Copyright (c) 2017, 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: Éder F. Zulian
// */
//#include <math.h>
//#include "RGR.h"
//#include "../ControllerCore.h"
//#include "../timingCalculations.h"
//#include "../../../common/utils.h"
//#define TRUE 1
//#define FALSE !(TRUE)
//#define INITIAL_DISPLACEMENT FALSE
//using namespace std;
//RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore),
// timing(ctrlcore.config.memSpec->refreshTimings[ccore.getBanks()[0]])
//{
// fmb = ccore.config.ControllerCoreRefForceMaxPostponeBurst;
// bwl = ccore.config.BankwiseLogic;
// ri = ccore.config.getRowInc();
// auto nr = ccore.config.memSpec->NumberOfRows;
// auto nar = ccore.config.getNumAR();
// auto m = ccore.config.getRefMode();
// rpr = (nr / m) / nar;
// assert(rpr > 0);
// tREFIx = timing.tREFI / m;
// trp = ccore.config.getTrpb();
// trcd = ccore.config.memSpec->tRCD;
// postponeEnabled = ccore.config.ControllerCoreRefEnablePostpone;
// pullInEnabled = ccore.config.ControllerCoreRefEnablePullIn;
// maxpostpone = ccore.config.ControllerCoreRefMaxPostponed * m;
// maxpullin = ccore.config.ControllerCoreRefMaxPulledIn * m;
// for (Bank b : ccore.getBanks()) {
// pulledin[b] = 0;
// postponed[b] = 0;
// currentState[b] = ST_REFRESH;
// previousState[b] = ST_REFRESH;
// nextState[b] = ST_REFRESH;
// setUpDummy(rps[b], b);
// }
//#if INITIAL_DISPLACEMENT == TRUE
// if (bwl) {
// auto nbs = ccore.config.memSpec->NumberOfBanks;
// for (Bank b : ccore.getBanks()) {
// nextPlannedRefreshs[b] = b.ID() * tREFIx / nbs;
// }
// }
//#else
// for (Bank b : ccore.getBanks()) {
// nextPlannedRefreshs[b] = SC_ZERO_TIME;
// }
//#endif
// if (bwl) {
// for (Bank b : ccore.getBanks()) {
// planNextRefresh(b, tREFIx, false);
// }
// } else {
// planNextRefresh(ccore.getBanks()[0], tREFIx, false);
// }
//}
//RGR::~RGR()
//{
//}
//bool RGR::hasCollision(const ScheduledCommand &cmd)
//{
// Bank b = cmd.getBank();
// if (currentState[b] == ST_BURST) {
// // A burst due to postponed refreshes shall not be interrupted.
// return true;
// }
// return false;
//}
//sc_time RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t)
//{
// sc_assert(!isInvalidated(p, t));
// Bank b = DramExtension::getExtension(p).getBank();
// bool openBank = ccore.state->rowBufferStates->rowBufferIsOpen(b);
// bool allClosed = ccore.state->rowBufferStates->allRowBuffersAreClosed();
// bool pre = bwl ? openBank : !allClosed;
// sc_time trfcx = SC_ZERO_TIME;
// if (!bwl) {
// for (Bank b : ccore.getBanks()) {
// currentRefresh[b] = t;
// }
// } else {
// currentRefresh[b] = t;
// }
// if (pre) {
// trfcx += trp;
// if (bwl) {
// if (ccore.config.getRGRBank(b.ID())) {
// ccore.scheduleRequest(Command::PREB, rps[b]);
// }
// } else {
// for (Bank b : ccore.getBanks()) {
// auto rgrb = ccore.config.getRGRBank(b.ID());
// if (ccore.state->rowBufferStates->rowBufferIsOpen(b) && rgrb) {
// ccore.scheduleRequest(Command::PREB, rps[Bank(b)]);
// }
// }
// }
// }
// for (unsigned r = 0; r < rpr; r += ri) {
// trfcx += trcd + trp;
// if (bwl) {
// if (ccore.config.getRGRBank(b.ID())) {
// ccore.scheduleRequest(Command::ACTB, rps[b]);
// ccore.scheduleRequest(Command::PREB, rps[b]);
// }
// DramExtension::getExtension(p).incrementRow();
// } else {
// for (Bank b : ccore.getBanks()) {
// if (ccore.config.getRGRBank(b.ID())) {
// ccore.scheduleRequest(Command::ACTB, rps[b]);
// ccore.scheduleRequest(Command::PREB, rps[b]);
// }
// DramExtension::getExtension(rps[b]).incrementRow();
// }
// }
// }
// return trfcx;
//}
//void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t)
//{
// sc_time nrt;
// sc_time trfcx;
// Bank b = DramExtension::getExtension(p).getBank();
// bool preq = bwl ? ccore.hasPendingRequests(b) : ccore.hasPendingRequests();
// bool postpone = postponeEnabled && preq && (postponed[b] < maxpostpone);
// bool pullIn = pullInEnabled && !preq && (pulledin[b] < maxpullin);
// previousState[b] = currentState[b];
// currentState[b] = nextState[b];
// bool align = false;
// switch (currentState[b]) {
// case ST_REFRESH:
// assert(pulledin[b] == 0 && postponed[b] == 0);
// if (postpone) {
// nrt = SC_ZERO_TIME;
// nextState[b] = ST_POSTPONE;
// } else if (pullIn) {
// trfcx = doRefresh(p, t);
// nrt = trfcx;
// nextState[b] = ST_PULLIN;
// } else {
// doRefresh(p, t);
// nrt = tREFIx;
// nextState[b] = ST_REFRESH;
// }
// break;
// case ST_PULLIN:
// if (pullIn) {
// trfcx = doRefresh(p, t);
// pulledin[b]++;
// nrt = trfcx;
// nextState[b] = ST_PULLIN;
// } else {
// nrt = SC_ZERO_TIME;
// nextState[b] = ST_ALIGN;
// }
// break;
// case ST_SKIP:
// if (pulledin[b] == 0) {
// nrt = SC_ZERO_TIME;
// nextState[b] = ST_REFRESH;
// } else {
// pulledin[b]--;
// nrt = tREFIx;
// nextState[b] = ST_SKIP;
// }
// break;
// case ST_POSTPONE:
// postponed[b]++;
// if ((postponed[b] > maxpostpone) || (!preq && !fmb)) {
// // Burst triggered by inactivity or max postpone value reached.
// nrt = SC_ZERO_TIME;
// nextState[b] = ST_BURST;
// } else {
// nrt = tREFIx;
// nextState[b] = ST_POSTPONE;
// }
// break;
// case ST_BURST:
// doRefresh(p, t);
// postponed[b]--;
// if (postponed[b] == 0) {
// nrt = SC_ZERO_TIME;
// nextState[b] = ST_ALIGN;
// } else {
// nrt = SC_ZERO_TIME;
// nextState[b] = ST_BURST;
// }
// break;
// case ST_ALIGN:
// nrt = tREFIx;
// align = true;
// if (previousState[b] == ST_PULLIN) {
// nextState[b] = ST_SKIP;
// } else {
// nextState[b] = ST_REFRESH;
// }
// break;
// default:
// SC_REPORT_FATAL(this->name(), "RGR flex FSM invalid state.");
// break;
// }
// planNextRefresh(bwl ? b : ccore.getBanks()[0], nrt, align);
//}
//void RGR::planNextRefresh(Bank b, sc_time t, bool align)
//{
// if (align) {
// nextPlannedRefreshs[b] = trunc(nextPlannedRefreshs[b].to_double() /
// tREFIx.to_double()) * tREFIx;
// }
// nextPlannedRefreshs[b] += t;
// ccore.controller.send(REFTrigger, nextPlannedRefreshs[b], rps[b]);
//}
//void RGR::reInitialize(Bank b, sc_time t)
//{
// nextPlannedRefreshs[b] = clkAlign(t, Alignment::DOWN);
// planNextRefresh(b, tREFIx, true);
//}
//bool RGR::isInvalidated(tlm::tlm_generic_payload &p, sc_time t)
//{
// return nextPlannedRefreshs[DramExtension::getExtension(p).getBank()] > t;
//}
//void RGR::printDebugMessage(std::string msg)
//{
// DebugManager::getInstance().printDebugMessage(this->name(), msg);
//}

View File

@@ -1,81 +0,0 @@
///*
// * Copyright (c) 2017, 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: Éder F. Zulian
// */
//#ifndef RGR_H
//#define RGR_H
//#include "../../../common/dramExtensions.h"
//#include "../configuration/MemSpec.h"
//#include "IRefreshManager.h"
//class ControllerCore;
//class RGR : public IRefreshManager, public sc_module
//{
//public:
// RGR(sc_module_name, ControllerCore &ctrlcore);
// virtual ~RGR();
// virtual bool hasCollision(const ScheduledCommand &cmd) override;
// virtual void scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) override;
// void reInitialize(Bank bank, sc_time time) override;
// bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) override;
//private:
// bool fmb;
// bool bwl;
// unsigned int ri;
// unsigned int rpr;
// sc_time trp;
// sc_time trcd;
// sc_time tREFIx;
// ControllerCore &ccore;
// RefreshTiming &timing;
// std::map<Bank, tlm::tlm_generic_payload> rps;
// std::map<Bank, sc_time> nextPlannedRefreshs;
// std::map<Bank, sc_time> currentRefresh;
// bool postponeEnabled;
// bool pullInEnabled;
// unsigned int maxpostpone;
// unsigned int maxpullin;
// std::map<Bank, unsigned int> pulledin;
// std::map<Bank, unsigned int> postponed;
// std::map<Bank, ref_fsm_state_t> currentState;
// std::map<Bank, ref_fsm_state_t> previousState;
// std::map<Bank, ref_fsm_state_t> nextState;
// sc_time doRefresh(tlm::tlm_generic_payload &p, sc_time t);
// void planNextRefresh(Bank b, sc_time t, bool align);
// void printDebugMessage(std::string message);
//};
//#endif // RGR_H

View File

@@ -1,275 +0,0 @@
///*
// * Copyright (c) 2015, 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.
// *
// * Authors:
// * Robert Gernhardt
// * Matthias Jung
// * Felipe S. Prado
// * Ana Mativi
// * Éder F. Zulian
// */
//#include "RefreshManager.h"
//#include "../ControllerCore.h"
//#include "../timingCalculations.h"
//#include "../../../common/utils.h"
//using namespace tlm;
//RefreshManager::RefreshManager(sc_module_name,
// ControllerCore &controller) : controllerCore(controller),
// timing(controller.config.memSpec->refreshTimings[Bank(0)])
//{
// auto m = controllerCore.config.getRefMode();
// tREFIx = timing.tREFI / m;
// tRFCx = timing.tRFC;
// postponeEnabled = controllerCore.config.ControllerCoreRefEnablePostpone;
// pullInEnabled = controllerCore.config.ControllerCoreRefEnablePullIn;
// maxpostpone = controllerCore.config.ControllerCoreRefMaxPostponed * m;
// maxpullin = controllerCore.config.ControllerCoreRefMaxPulledIn * m;
// pulledin = 0;
// postponed = 0;
// currentState = ST_REFRESH;
// previousState = ST_REFRESH;
// nextState = ST_REFRESH;
// nextPlannedRefresh = SC_ZERO_TIME;
// for (Bank bank : controller.getBanks()) {
// setUpDummy(refreshPayloads[bank], bank);
// }
// planNextRefresh(tREFIx, false);
//}
//RefreshManager::~RefreshManager()
//{
//}
////Check if a command will be scheduled during the next refresh period
//bool RefreshManager::hasCollision(const ScheduledCommand &command)
//{
// bool collisionWithPreviousRefEnd = command.getStart() <
// controllerCore.state->getLastCommand(Command::REFA).getEnd();
// bool collisionWithNextRefStart = command.getEnd() >= nextPlannedRefresh;
// if (controllerCore.config.ControllerCoreRefEnablePostpone
// && (postponed < maxpostpone)) {
// // Flexible refresh is on and have "credits" to postpone.
// // Then there will not be a collision with next refresh because
// // nextPlannedRefresh will be updated.
// collisionWithNextRefStart = false;
// }
// if (currentState == ST_BURST) {
// // A burst due to postponed refreshes shall not be interrupted.
// collisionWithNextRefStart = true;
// }
// return collisionWithPreviousRefEnd || collisionWithNextRefStart;
//}
//bool RefreshManager::doRefresh(tlm::tlm_generic_payload &payload, sc_time time)
//{
// sc_assert(!isInvalidated(payload, time));
// bool pre = false;
// // If any row is open, precharge all.
// if (!controllerCore.state->rowBufferStates->allRowBuffersAreClosed()) {
// pre = true;
// ScheduledCommand prechargeAllMaster(Command::PREA, time,
// Configuration::getInstance().memSpec->getExecutionTime(
// Command::PREA, refreshPayloads[Bank(0)]),
// refreshPayloads[Bank(0)]);
// controllerCore.getCommandChecker(
// Command::PREA).delayToSatisfyConstraints(prechargeAllMaster);
// for (size_t i = 1; i < controllerCore.getBanks().size(); i++) {
// ScheduledCommand prechargeAll(Command::PREA,
// prechargeAllMaster.getStart(), prechargeAllMaster.getExecutionTime(),
// refreshPayloads[Bank(i)]);
// controllerCore.state->change(prechargeAll);
// }
// controllerCore.state->change(prechargeAllMaster);
// controllerCore.controller.send(prechargeAllMaster, refreshPayloads[Bank(0)]);
// }
// //Otherwise just the AutoRefresh command is scheduled.
// ScheduledCommand refreshAllMaster(Command::REFA, time,
// Configuration::getInstance().memSpec->getExecutionTime(
// Command::REFA, refreshPayloads[Bank(0)]),
// DramExtension::getExtension(refreshPayloads[Bank(0)]));
// controllerCore.getCommandChecker(
// Command::REFA).delayToSatisfyConstraints(refreshAllMaster);
// for (size_t i = 1; i < controllerCore.getBanks().size(); i++) {
// ScheduledCommand refresh(Command::REFA, refreshAllMaster.getStart(),
// refreshAllMaster.getExecutionTime(), refreshPayloads[Bank(i)]);
// controllerCore.state->change(refresh);
// DramExtension::getExtension(refreshPayloads[Bank(i)]).incrementRow();
// }
// controllerCore.state->change(refreshAllMaster);
// DramExtension::getExtension(refreshPayloads[Bank(0)]).incrementRow();
// controllerCore.controller.send(refreshAllMaster, refreshPayloads[Bank(0)]);
// return pre;
//}
//void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload,
// sc_time time)
//{
// sc_time nextRefTiming;
// bool pendingReq = controllerCore.hasPendingRequests();
// bool canPostpone = postponeEnabled && pendingReq && (postponed < maxpostpone);
// bool canPullIn = pullInEnabled && !pendingReq && (pulledin < maxpullin);
// previousState = currentState;
// currentState = nextState;
// bool align = false;
// sc_time nrt;
// bool pre;
// switch (currentState) {
// case ST_REFRESH:
// // Regular Refresh. It's possible to migrate from this to the flexible
// // refresh states
// assert(pulledin == 0 && postponed == 0);
// if (canPostpone) {
// nextRefTiming = SC_ZERO_TIME;
// nextState = ST_POSTPONE;
// } else if (canPullIn) {
// pre = doRefresh(payload, time);
// nrt = tRFCx;
// if (pre)
// nrt += controllerCore.config.memSpec->tRP_old;
// nextRefTiming = nrt;
// nextState = ST_PULLIN;
// } else {
// doRefresh(payload, time);
// nextRefTiming = tREFIx;
// nextState = ST_REFRESH;
// }
// break;
// case ST_PULLIN:
// // Pull-in a refresh. Try to pull-in refreshes as long it is possible.
// if (canPullIn) {
// pulledin++;
// pre = doRefresh(payload, time);
// nrt = tRFCx;
// if (pre)
// nrt += controllerCore.config.memSpec->tRP_old;
// nextRefTiming = nrt;
// nextState = ST_PULLIN;
// } else {
// nextRefTiming = SC_ZERO_TIME;
// nextState = ST_ALIGN;
// }
// break;
// case ST_SKIP:
// // Skip the pulled-in refreshes.
// if (pulledin == 0) {
// nextRefTiming = SC_ZERO_TIME;
// nextState = ST_REFRESH;
// } else {
// pulledin--;
// nextRefTiming = tREFIx;
// nextState = ST_SKIP;
// }
// break;
// case ST_POSTPONE:
// // Postpone Refresh. Delaying refreshes as long as there are pending
// // requests and credits to postpone. Should be followed by a burst
// // refresh.
// postponed++;
// if ((postponed > maxpostpone) || (!pendingReq
// && !controllerCore.config.ControllerCoreRefForceMaxPostponeBurst)) {
// // Burst triggered by inactivity or max postpone value reached.
// nextRefTiming = SC_ZERO_TIME;
// nextState = ST_BURST;
// } else {
// nextRefTiming = tREFIx;
// nextState = ST_POSTPONE;
// }
// break;
// case ST_BURST:
// // Burst postponed refreshes.
// pre = doRefresh(payload, time);
// postponed--;
// if (postponed == 0) {
// // All refreshes issued, next state will align to tREFIx
// nextRefTiming = SC_ZERO_TIME;
// nextState = ST_ALIGN;
// } else {
// nrt = tRFCx;
// if (pre)
// nrt += controllerCore.config.memSpec->tRP_old;
// nextRefTiming = nrt;
// nextState = ST_BURST;
// }
// break;
// case ST_ALIGN:
// // Align Refresh. Adjusting the timing so the next REF timing will be
// // a in a time multiple of tREFIx
// nextRefTiming = tREFIx;
// align = true;
// if (previousState == ST_PULLIN) {
// nextState = ST_SKIP;
// } else {
// nextState = ST_REFRESH;
// }
// break;
// default:
// SC_REPORT_FATAL(this->name(), "Invalid state in flexible refresh FSM.");
// break;
// }
// planNextRefresh(nextRefTiming, align);
//}
//void RefreshManager::planNextRefresh(sc_time nextRefTiming, bool align)
//{
// if (align) {
// nextPlannedRefresh = trunc(nextPlannedRefresh.to_double() / tREFIx.to_double())
// * tREFIx;
// }
// nextPlannedRefresh += nextRefTiming;
// controllerCore.controller.send(REFTrigger, nextPlannedRefresh,
// refreshPayloads[Bank(0)]);
//}
//void RefreshManager::reInitialize(Bank, sc_time time)
//{
// nextPlannedRefresh = clkAlign(time, Alignment::DOWN);
// planNextRefresh(tREFIx, true);
//}
//bool RefreshManager::isInvalidated(tlm::tlm_generic_payload &payload
// __attribute__((unused)), sc_time time)
//{
// return nextPlannedRefresh > time;
//}
//void RefreshManager::printDebugMessage(std::string message)
//{
// DebugManager::getInstance().printDebugMessage(this->name(), message);
//}

View File

@@ -1,82 +0,0 @@
///*
// * Copyright (c) 2015, 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.
// *
// * Authors:
// * Robert Gernhardt
// * Matthias Jung
// * Éder F. Zulian
// */
//#ifndef REFRESHMANAGER_H
//#define REFRESHMANAGER_H
//#include "IRefreshManager.h"
//#include "../configuration/MemSpec.h"
//class ControllerCore;
//class RefreshManager : public IRefreshManager, public sc_module
//{
//public:
// RefreshManager(sc_module_name /*name*/, ControllerCore &controllerCore);
// virtual ~RefreshManager();
// virtual bool hasCollision(const ScheduledCommand &command) override;
// virtual void scheduleRefresh(tlm::tlm_generic_payload &payload,
// sc_time time) override;
// void reInitialize(Bank bank, sc_time time) override;
// virtual bool isInvalidated(tlm::tlm_generic_payload &payload,
// sc_time time) override;
//private:
// ControllerCore &controllerCore;
// RefreshTiming &timing;
// sc_time nextPlannedRefresh;
// sc_time tREFIx;
// sc_time tRFCx;
// std::map<Bank, tlm::tlm_generic_payload> refreshPayloads;
// bool postponeEnabled;
// bool pullInEnabled;
// unsigned int maxpostpone;
// unsigned int maxpullin;
// unsigned int pulledin;
// unsigned int postponed;
// ref_fsm_state_t currentState;
// ref_fsm_state_t previousState;
// ref_fsm_state_t nextState;
// bool doRefresh(tlm::tlm_generic_payload &payload, sc_time time);
// void planNextRefresh(sc_time time, bool align);
// void printDebugMessage(std::string message);
//};
//#endif // REFRESHMANAGER_H

View File

@@ -1,265 +0,0 @@
///*
// * Copyright (c) 2015, 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.
// *
// * Authors:
// * Janik Schlemminger
// * Matthias Jung
// * Éder F. Zulian
// */
//#include "RefreshManagerBankwise.h"
//#include "../ControllerCore.h"
//#include "../timingCalculations.h"
//#include "../../../common/utils.h"
//using namespace std;
//RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name,
// ControllerCore &controller) : controllerCore(controller),
// timing(controller.config.memSpec->refreshTimings[Bank(0)])
//{
// auto m = controllerCore.config.getRefMode();
// tREFIx = timing.tREFI / m;
// tRFCx = timing.tRFC;
// postponeEnabled = controllerCore.config.ControllerCoreRefEnablePostpone;
// pullInEnabled = controllerCore.config.ControllerCoreRefEnablePullIn;
// maxpostpone = controllerCore.config.ControllerCoreRefMaxPostponed * m;
// maxpullin = controllerCore.config.ControllerCoreRefMaxPulledIn * m;
// for (Bank bank : controller.getBanks()) {
// nextPlannedRefreshs[bank] = SC_ZERO_TIME;
// pulledin[bank] = 0;
// postponed[bank] = 0;
// currentState[bank] = ST_REFRESH;
// previousState[bank] = ST_REFRESH;
// nextState[bank] = ST_REFRESH;
// setUpDummy(refreshPayloads[bank], bank);
// planNextRefresh(bank, tREFIx, false);
// }
//}
//RefreshManagerBankwise::~RefreshManagerBankwise()
//{
//}
//bool RefreshManagerBankwise::hasCollision(const ScheduledCommand &command)
//{
// Bank bank = command.getBank();
// bool collisionWithPreviousRefEnd = command.getStart() <
// controllerCore.state->getLastCommand(Command::REFA, bank).getEnd();
// bool collisionWithNextRefStart = command.getEnd() >= nextPlannedRefreshs[bank];
// if (controllerCore.config.ControllerCoreRefEnablePostpone
// && (postponed[bank] < maxpostpone)) {
// // Flexible refresh is on and have "credits" to postpone.
// // Then there will not be a collision with next refresh because
// // nextPlannedRefresh will be updated.
// collisionWithNextRefStart = false;
// }
// if (currentState[bank] == ST_BURST) {
// // A burst due to postponed refreshes shall not be interrupted.
// collisionWithNextRefStart = true;
// }
// return collisionWithPreviousRefEnd || collisionWithNextRefStart;
//}
//bool RefreshManagerBankwise::doRefresh(tlm::tlm_generic_payload &payload,
// sc_time time)
//{
// sc_assert(!isInvalidated(payload, time));
// bool pre = false;
// tlm::tlm_generic_payload &refreshPayload =
// refreshPayloads[DramExtension::getExtension(payload).getBank()];
// DramExtension &extension = DramExtension::getExtension(refreshPayload);
// if (controllerCore.state->rowBufferStates->rowBufferIsOpen(
// extension.getBank())) {
// pre = true;
// ScheduledCommand precharge(Command::PRE, time,
// Configuration::getInstance().memSpec->getExecutionTime(
// Command::PRE, refreshPayload), extension);
// controllerCore.getCommandChecker(Command::PRE).delayToSatisfyConstraints(
// precharge);
// controllerCore.state->change(precharge);
// controllerCore.controller.send(precharge, refreshPayload);
// }
// ScheduledCommand refresh(Command::REFA, time,
// Configuration::getInstance().memSpec->getExecutionTime(
// Command::REFA, refreshPayload), extension);
// controllerCore.getCommandChecker(
// Command::REFA).delayToSatisfyConstraints(refresh);
// controllerCore.state->change(refresh);
// extension.incrementRow();
// controllerCore.controller.send(refresh, refreshPayload);
// return pre;
//}
//void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
// sc_time time)
//{
// sc_time nextRefTiming;
// Bank bank = DramExtension::getExtension(payload).getBank();
// bool pendingReq = controllerCore.hasPendingRequests(bank);
// bool canPostpone = postponeEnabled && pendingReq
// && (postponed[bank] < maxpostpone);
// bool canPullIn = pullInEnabled && !pendingReq && (pulledin[bank] < maxpullin);
// previousState[bank] = currentState[bank];
// currentState[bank] = nextState[bank];
// bool align = false;
// sc_time nrt;
// bool pre;
// switch (currentState[bank]) {
// case ST_REFRESH:
// // Regular Refresh. It's possible to migrate from this to the flexible
// // refresh states
// assert(pulledin[bank] == 0 && postponed[bank] == 0);
// if (canPostpone) {
// nextRefTiming = SC_ZERO_TIME;
// nextState[bank] = ST_POSTPONE;
// } else if (canPullIn) {
// pre = doRefresh(payload, time);
// nrt = tRFCx;
// if (pre)
// nrt += controllerCore.config.memSpec->tRP_old;
// nextRefTiming = nrt;
// nextState[bank] = ST_PULLIN;
// } else {
// doRefresh(payload, time);
// nextRefTiming = tREFIx;
// nextState[bank] = ST_REFRESH;
// }
// break;
// case ST_PULLIN:
// // Pull-in a refresh. Try to pull-in refreshes as long it is possible.
// if (canPullIn) {
// pulledin[bank]++;
// pre = doRefresh(payload, time);
// nrt = tRFCx;
// if (pre)
// nrt += controllerCore.config.memSpec->tRP_old;
// nextRefTiming = nrt;
// nextState[bank] = ST_PULLIN;
// } else {
// nextRefTiming = SC_ZERO_TIME;
// nextState[bank] = ST_ALIGN;
// }
// break;
// case ST_SKIP:
// // Skip the pulled-in refreshes.
// if (pulledin[bank] == 0) {
// nextRefTiming = SC_ZERO_TIME;
// nextState[bank] = ST_REFRESH;
// } else {
// pulledin[bank]--;
// nextRefTiming = tREFIx;
// nextState[bank] = ST_SKIP;
// }
// break;
// case ST_POSTPONE:
// // Postpone Refresh. Delaying refreshes as long as there are pending
// // requests and credits to postpone. Should be followed by a burst
// // refresh.
// postponed[bank]++;
// if ((postponed[bank] > maxpostpone) || (!pendingReq
// && !controllerCore.config.ControllerCoreRefForceMaxPostponeBurst)) {
// // Burst triggered by inactivity or max postpone value reached.
// nextRefTiming = SC_ZERO_TIME;
// nextState[bank] = ST_BURST;
// } else {
// nextRefTiming = tREFIx;
// nextState[bank] = ST_POSTPONE;
// }
// break;
// case ST_BURST:
// // Burst postponed refreshes.
// pre = doRefresh(payload, time);
// postponed[bank]--;
// if (postponed[bank] == 0) {
// // All refreshes issued, next state will align to tREFIx
// nextRefTiming = SC_ZERO_TIME;
// nextState[bank] = ST_ALIGN;
// } else {
// nrt = tRFCx;
// if (pre)
// nrt += controllerCore.config.memSpec->tRP_old;
// nextRefTiming = nrt;
// nextState[bank] = ST_BURST;
// }
// break;
// case ST_ALIGN:
// // Align Refresh. Adjusting the timing so the next REF timing will be
// // a in a time multiple of tREFIx
// nextRefTiming = tREFIx;
// align = true;
// if (previousState[bank] == ST_PULLIN) {
// nextState[bank] = ST_SKIP;
// } else {
// nextState[bank] = ST_REFRESH;
// }
// break;
// default:
// SC_REPORT_FATAL(this->name(), "Invalid state in bw flex. ref. FSM.");
// break;
// }
// planNextRefresh(bank, nextRefTiming, align);
//}
//void RefreshManagerBankwise::planNextRefresh(Bank bank, sc_time nextRefTiming,
// bool align)
//{
// if (align) {
// nextPlannedRefreshs[bank] = trunc(nextPlannedRefreshs[bank].to_double() /
// tREFIx.to_double()) * tREFIx;
// }
// nextPlannedRefreshs[bank] += nextRefTiming;
// controllerCore.controller.send(REFTrigger, nextPlannedRefreshs[bank],
// refreshPayloads[bank]);
//}
//void RefreshManagerBankwise::reInitialize(Bank bank, sc_time time)
//{
// nextPlannedRefreshs[bank] = clkAlign(time, Alignment::DOWN);
// planNextRefresh(bank, tREFIx, true);
//}
//bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload &payload,
// sc_time time)
//{
// return nextPlannedRefreshs[DramExtension::getExtension(payload).getBank()] >
// time;
//}
//void RefreshManagerBankwise::printDebugMessage(std::string message)
//{
// DebugManager::getInstance().printDebugMessage(this->name(), message);
//}

View File

@@ -1,83 +0,0 @@
///*
// * Copyright (c) 2015, 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.
// *
// * Authors:
// * Janik Schlemminger
// * Matthias Jung
// * Éder F. Zulian
// */
//#ifndef REFRESHMANAGERBANKWISE_H
//#define REFRESHMANAGERBANKWISE_H
////#include "../../../common/dramExtension.h"
//#include "IRefreshManager.h"
//#include "../configuration/MemSpec.h"
//class ControllerCore;
//class RefreshManagerBankwise : public IRefreshManager, public sc_module
//{
//public:
// RefreshManagerBankwise(sc_module_name /*name*/, ControllerCore &controllerCore);
// virtual ~RefreshManagerBankwise();
// virtual bool hasCollision(const ScheduledCommand &command) override;
// virtual void scheduleRefresh(tlm::tlm_generic_payload &payload,
// sc_time time) override;
// void reInitialize(Bank bank, sc_time time) override;
// bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) override;
//private:
// ControllerCore &controllerCore;
// RefreshTiming &timing;
// std::map<Bank, sc_time> nextPlannedRefreshs;
// sc_time tREFIx;
// sc_time tRFCx;
// std::map<Bank, tlm::tlm_generic_payload> refreshPayloads;
// bool postponeEnabled;
// bool pullInEnabled;
// unsigned int maxpostpone;
// unsigned int maxpullin;
// std::map<Bank, unsigned int> pulledin;
// std::map<Bank, unsigned int> postponed;
// std::map<Bank, ref_fsm_state_t> currentState;
// std::map<Bank, ref_fsm_state_t> previousState;
// std::map<Bank, ref_fsm_state_t> nextState;
// bool doRefresh(tlm::tlm_generic_payload &payload, sc_time time);
// void planNextRefresh(Bank bank, sc_time time, bool align);
// void printDebugMessage(std::string message);
//};
//#endif // REFRESHMANAGERBANKWISE_H

View File

@@ -1,144 +0,0 @@
/*
* Copyright (c) 2017, 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: Éder F. Zulian
*/
#include <iostream>
#include <algorithm>
#include <set>
#include "ActBChecker.h"
#include "../../timingCalculations.h"
#include "../../../../common/DebugManager.h"
#include "../../../Command.h"
#include "../../../../common/utils.h"
using namespace std;
void ActBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const
{
sc_assert(cmd.getCommand() == Command::ACTB);
ScheduledCommand lcb = state.getLastScheduledCommand(cmd.getBank());
if (lcb.isValidCommand()) {
if (lcb.getCommand() == Command::PREB) {
cmd.establishMinDistanceFromStart(lcb.getStart(),
Configuration::getInstance().getTrpb());
} else if (lcb.getCommand() == Command::PRE
|| lcb.getCommand() == Command::PREA) {
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRP_old);
} else if (lcb.getCommand() == Command::RDA) {
cmd.establishMinDistanceFromStart(lcb.getStart(),
config.memSpec->tRTP + config.memSpec->tRP_old);
} else if (lcb.getCommand() == Command::WRA) {
cmd.establishMinDistanceFromStart(lcb.getStart(),
config.memSpec->tWL + config.memSpec->getWriteAccessTime()
+ config.memSpec->tWR + config.memSpec->tRP_old);
} else if (lcb.getCommand() == Command::REFA) {
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRFC_old);
} else if (lcb.getCommand() == Command::PDXP
|| lcb.getCommand() == Command::PDXA) {
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tXP);
} else if (lcb.getCommand() == Command::SREFEX) {
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tXS);
} else {
reportFatal("ActB Checker",
"ACTB can not follow " + commandToString(lcb.getCommand()));
}
}
ScheduledCommand lc;
if ((lc = state.getLastCommand(Command::PREA)).isValidCommand()) {
cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec->tRP_old);
}
delay_to_satisfy_activateToActivate_sameBank(cmd);
while (!(state.bus.isFree(cmd.getStart())
&& satsfies_activateToActivate_differentBank(cmd)
&& satisfies_nActivateWindow(cmd))) {
cmd.delayStart(config.memSpec->clk);
}
}
void ActBChecker::delay_to_satisfy_activateToActivate_sameBank(
ScheduledCommand &cmd) const
{
ScheduledCommand lastActOnBank = state.getLastCommandOnBank(Command::ACT,
cmd.getBank());
if (lastActOnBank.isValidCommand()) {
cmd.establishMinDistanceFromStart(lastActOnBank.getStart(), config.memSpec->tRC);
}
ScheduledCommand lastActBOnBank = state.getLastCommandOnBank(Command::ACTB,
cmd.getBank());
if (lastActBOnBank.isValidCommand()) {
cmd.establishMinDistanceFromStart(lastActBOnBank.getStart(),
Configuration::getInstance().getTrcb());
}
}
bool ActBChecker::satsfies_activateToActivate_differentBank(
ScheduledCommand &cmd) const
{
for (auto act : state.lastActivatesB) {
sc_time t = act.first, tRRD = (cmd.getBankGroup() == act.second.getBankGroup() ?
Configuration::getInstance().getTrrdb_L() :
Configuration::getInstance().getTrrdb_S());
if ((t < cmd.getStart() && cmd.getStart() - t < tRRD) || (cmd.getStart() <= t
&& t - cmd.getStart() < tRRD)) {
return false;
}
}
// for (auto act : state.lastActivates) {
// sc_time t = act.first, tRRD = (cmd.getBankGroup() == act.second.getBankGroup() ?
// config.memSpec->tRRD_L_old : config.memSpec->tRRD_S_old);
// if ((t < cmd.getStart() && cmd.getStart() - t < tRRD) || (cmd.getStart() <= t
// && t - cmd.getStart() < tRRD)) {
// return false;
// }
// }
return true;
}
bool ActBChecker::satisfies_nActivateWindow(ScheduledCommand &cmd) const
{
if (state.lastActivatesB.size() >= config.memSpec->nActivate) {
map<sc_time, ScheduledCommand>lastActivates = state.lastActivatesB;
lastActivates.emplace(cmd.getStart(), cmd);
auto upper = lastActivates.begin();
advance(upper, config.memSpec->nActivate);
auto lower = lastActivates.begin();
while (upper != lastActivates.end()) {
if (upper->first - lower->first < Configuration::getInstance().getTfawb()) {
return false;
}
++upper;
++lower;
}
}
return true;
}

View File

@@ -1,60 +0,0 @@
/*
* Copyright (c) 2017, 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: Éder F. Zulian
*/
#ifndef ACTBCHECKER_H
#define ACTBCHECKER_H
#include <map>
#include "ICommandChecker.h"
#include "../../configuration/Configuration.h"
#include "../../../ControllerState.h"
class ActBChecker : public ICommandChecker
{
public:
ActBChecker(const Configuration &config,
ControllerState &state) : config(config), state(state) {}
virtual ~ActBChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const
override;
private:
const Configuration &config;
ControllerState &state;
void delay_to_satisfy_activateToActivate_sameBank(ScheduledCommand &command)
const;
bool satsfies_activateToActivate_differentBank(ScheduledCommand &command) const;
bool satisfies_nActivateWindow(ScheduledCommand &command) const;
};
#endif // ACTBCHECKER_H

View File

@@ -1,148 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#include <iostream>
#include <algorithm>
#include <set>
#include "ActivateChecker.h"
#include "../../timingCalculations.h"
#include "../../../../common/DebugManager.h"
#include "../../../Command.h"
#include "../../../../common/utils.h"
using namespace std;
void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
{
sc_assert(command.getCommand() == Command::ACT);
ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(
command.getBank());
if (lastCommandOnBank.isValidCommand()) {
if (lastCommandOnBank.getCommand() == Command::PREB
|| lastCommandOnBank.getCommand() == Command::PRE
|| lastCommandOnBank.getCommand() == Command::PREA) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tRP_old);
} else if (lastCommandOnBank.getCommand() == Command::RDA) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tRTP + config.memSpec->tRP_old);
} else if (lastCommandOnBank.getCommand() == Command::WRA) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tWL + config.memSpec->getWriteAccessTime()
+ config.memSpec->tWR + config.memSpec->tRP_old);
} else if (lastCommandOnBank.getCommand() == Command::REFA) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tRFC_old);
} else if (lastCommandOnBank.getCommand() == Command::PDXP
|| lastCommandOnBank.getCommand() == Command::PDXA) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tXP);
} else if (lastCommandOnBank.getCommand() == Command::SREFEX) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tXS);
} else
reportFatal("Activate Checker",
"ACT 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))) {
command.delayStart(config.memSpec->clk);
}
}
void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank(
ScheduledCommand &command) const
{
ScheduledCommand lastActivateOnBank = state.getLastCommandOnBank(Command::ACT,
command.getBank());
if (lastActivateOnBank.isValidCommand()) {
command.establishMinDistanceFromStart(lastActivateOnBank.getStart(),
config.memSpec->tRC);
}
ScheduledCommand lastActBOnBank = state.getLastCommandOnBank(Command::ACTB,
command.getBank());
if (lastActBOnBank.isValidCommand()) {
command.establishMinDistanceFromStart(lastActivateOnBank.getStart(),
config.memSpec->tRC);
}
}
bool ActivateChecker::satsfies_activateToActivate_differentBank(
ScheduledCommand &command) const
{
// for (auto act : state.lastActivates) {
// sc_time time = act.first;
// sc_time tRRD = (command.getBankGroup() == act.second.getBankGroup()) ?
// config.memSpec->tRRD_L_old : config.memSpec->tRRD_S_old;
// if ((time < command.getStart() && command.getStart() - time < tRRD)
// || (command.getStart() <= time && time - command.getStart() < tRRD))
// return false;
// }
return true;
}
bool ActivateChecker::satisfies_nActivateWindow(ScheduledCommand &command) const
{
/*
* there may be activates scheduled in the future, so emplace
* command in a copied set (not necessarily the last in time),
* and check if the n-act constraint holds for the whole set.
*/
// if (state.lastActivates.size() >= config.memSpec->nActivate) {
// map<sc_time, ScheduledCommand> lastActivates = state.lastActivates;
// lastActivates.emplace(command.getStart(), command);
// auto upper = lastActivates.begin();
// advance(upper, config.memSpec->nActivate);
// auto lower = lastActivates.begin();
// while (upper != lastActivates.end()) {
// if (upper->first - lower->first < config.memSpec->tNAW_old)
// return false;
// ++upper;
// ++lower;
// }
// }
return true;
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#ifndef ACTIVATECHECKER_H
#define ACTIVATECHECKER_H
#include <map>
#include "ICommandChecker.h"
#include "../../configuration/Configuration.h"
#include "../../../ControllerState.h"
class ActivateChecker: public ICommandChecker
{
public:
ActivateChecker(const Configuration &config,
ControllerState &state) : config(config), state(state) {}
virtual ~ActivateChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const
override;
private:
const Configuration &config;
ControllerState &state;//TODO make const
void delay_to_satisfy_activateToActivate_sameBank(ScheduledCommand &command)
const;
bool satsfies_activateToActivate_differentBank(ScheduledCommand &command) const;
bool satisfies_nActivateWindow(ScheduledCommand &command) const;
};
#endif // ACTIVATECHECKER_H

View File

@@ -1,205 +0,0 @@
/*
* 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 "CheckerDDR3New.h"
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include "../../timingCalculations.h"
#include "../../../../common/DebugManager.h"
#include "../../../Command.h"
#include "../../../../common/utils.h"
using namespace std;
sc_time CheckerDDR3New::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 = max(minTimeToWait, lastCommand.getStart() + memSpec->tRTP + memSpec->tRP);
lastCommand = lastScheduledByCommandAndBank[Command::WRA][bank];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP);
lastCommand = lastScheduledByCommandAndBank[Command::PRE][bank];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRP);
lastCommand = lastScheduledByCommand[Command::PREA];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRP);
lastCommand = lastScheduledByCommand[Command::PDXA];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
lastCommand = lastScheduledByCommand[Command::PDXP];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
lastCommand = lastScheduledByCommand[Command::REFA];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRFC);
lastCommand = lastScheduledByCommand[Command::SREFEX];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXS);
lastCommand = lastScheduledByCommandAndBank[Command::ACT][bank];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRC);
lastCommand = lastScheduledByCommand[Command::ACT];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRRD);
minTimeToWait = max(minTimeToWait, timeToSatisfyFAW());
}
else if (command == Command::RD || command == Command::RDA)
{
lastCommand = lastScheduledByCommandAndBank[Command::ACT][bank];
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRCD);
lastCommand = lastScheduledByCommand[Command::PDXA];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
lastCommand = lastScheduledByCommand[Command::SREFEX];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXSDLL);
lastCommand = lastScheduledByCommand[Command::RD];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD);
lastCommand = lastScheduledByCommand[Command::WR];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWTR);
}
else if (command == Command::WR || command == Command::WRA)
{
lastCommand = lastScheduledByCommandAndBank[Command::ACT][bank];
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRCD);
lastCommand = lastScheduledByCommand[Command::PDXA];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
lastCommand = lastScheduledByCommand[Command::SREFEX];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXSDLL);
lastCommand = lastScheduledByCommand[Command::RD];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL);
lastCommand = lastScheduledByCommand[Command::WR];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD);
}
else if (command == Command::PRE)
{
lastCommand = lastScheduledByCommandAndBank[Command::ACT][bank];
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRAS);
lastCommand = lastScheduledByCommandAndBank[Command::RD][bank];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRTP);
lastCommand = lastScheduledByCommandAndBank[Command::WR][bank];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWR);
lastCommand = lastScheduledByCommand[Command::PDXA];
if (lastCommand.isValidCommand())
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
}
else
{
reportFatal("CheckerDDR3New", "Unknown command!");
}
// Check if bus is free
if (lastScheduled.isValidCommand())
minTimeToWait = max(minTimeToWait, lastScheduled.getStart() + memSpec->clk);
return (minTimeToWait - sc_time_stamp());
}
sc_time CheckerDDR3New::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 CheckerDDR3New::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());
}
}
void CheckerDDR3New::printDebugMessage(std::string message)
{
DebugManager::getInstance().printDebugMessage("Checker", message);
}

View File

@@ -1,78 +0,0 @@
/*
* 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 CHECKERDDR3NEW_H
#define CHECKERDDR3NEW_H
#include <systemc.h>
#include <map>
#include <queue>
#include "../ScheduledCommand.h"
#include "../../configuration/Configuration.h"
#include "../../configuration/MemSpec.h"
#include "../../../Command.h"
#include "../../../../common/dramExtensions.h"
class CheckerDDR3New
{
public:
CheckerDDR3New()
{
memSpec = dynamic_cast<MemSpecDDR3 *>(Configuration::getInstance().memSpec);
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
}
~CheckerDDR3New() {}
sc_time delayToSatisfyConstraints(Command command, Bank bank);
void insert(const ScheduledCommand &scheduledCommand);
private:
const MemSpecDDR3 *memSpec;
std::map<Command, std::map<Bank, ScheduledCommand>> lastScheduledByCommandAndBank;
std::map<Command, ScheduledCommand> lastScheduledByCommand;
ScheduledCommand lastScheduled;
// Four activate window
std::queue<sc_time> lastActivates;
sc_time timeToSatisfyFAW();
//PowerDown TODO: Implement this method?
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
void printDebugMessage(std::string message);
};
#endif // CHECKERDDR3NEW_H

View File

@@ -1,53 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#ifndef ICOMMANDCHECKER_H
#define ICOMMANDCHECKER_H
#include <systemc.h>
#include "../ScheduledCommand.h"
class ICommandChecker
{
public:
virtual ~ICommandChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const = 0;
};
#endif // ICOMMANDCHECKER_H

View File

@@ -1,134 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
* Felipe S. Prado
*/
#include "PowerDownChecker.h"
#include "../../timingCalculations.h"
void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand &command)
const
{
sc_assert(command.commandIsIn({Command::PDEA, Command::PDEP, Command::SREFEN, Command::PDXA, Command::PDXP, Command::SREFEX}));
// Power Down commmand (one of the listed above)
Command pdnCmd = command.getCommand();
Bank bank = command.getBank();
sc_time timeConstraint;
if (pdnCmd == Command::PDEA || pdnCmd == Command::PDEP
|| pdnCmd == Command::SREFEN) {
// Entering in one of the Power Down modes:
// PDNA - Active Power Down
// PDNP - Precharge Power Down
// SREF - Self Refresh
// Get the last scheduled command
ScheduledCommand lastSchedCmd;
if(Configuration::getInstance().BankwiseLogic)
{
lastSchedCmd = state.getLastScheduledCommand(bank);
}
else
{
lastSchedCmd = state.getLastScheduledCommand();
}
// TODO: Why do we only need to check the last scheduled command? bank_0_RDA -> bank_1_PRE -> SREFEN violates timing
if (lastSchedCmd.isValidCommand()) {
// Get the start time for the last scheduled command
sc_time lastSchedCmdStart = lastSchedCmd.getStart();
// Get the last command
Command lastCmd = lastSchedCmd.getCommand();
timeConstraint = getTimeConstraintToEnterPowerDown(lastCmd, pdnCmd);
command.establishMinDistanceFromStart(lastSchedCmdStart, timeConstraint);
}
} else if (pdnCmd == Command::PDXA) {
// Leaving Active Power Down
timeConstraint = config.memSpec->tCKE;
command.establishMinDistanceFromStart(state.getLastCommandOnBank(Command::PDEA,
bank).getStart(), timeConstraint);
} else if (pdnCmd == Command::PDXP) {
// Leaving Precharge Power Down
timeConstraint = config.memSpec->tCKE;
command.establishMinDistanceFromStart(state.getLastCommandOnBank(Command::PDEP,
bank).getStart(), timeConstraint);
} else if (pdnCmd == Command::SREFEX) {
// Leaving Self Refresh
timeConstraint = config.memSpec->tCKESR;
command.establishMinDistanceFromStart(state.getLastCommandOnBank(Command::SREFEN,
bank).getStart(), timeConstraint);
}
state.bus.moveCommandToNextFreeSlot(command);
}
sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd,
Command pdnCmd) const
{
sc_assert(pdnCmd == Command::SREFEN || pdnCmd == Command::PDEA
|| pdnCmd == Command::PDEP);
sc_time constraint;
if (lastCmd == Command::RD || lastCmd == Command::RDA) {
constraint = config.memSpec->tRL + config.memSpec->getReadAccessTime() + config.memSpec->clk;
} else if (lastCmd == Command::WR) {
constraint = config.memSpec->tWL + config.memSpec->getWriteAccessTime() + config.memSpec->tWR;
} else if (lastCmd == Command::WRA) {
constraint = config.memSpec->tWL + config.memSpec->getWriteAccessTime() + config.memSpec->tWR +
config.memSpec->clk;
// TODO: for SREFEN the constraint is tRFC, for PDEP it is tREFPDEN, PDEA cannot be the next command after REFA (all banks closed)
} else if (lastCmd == Command::REFA) {
constraint = config.memSpec->tRFC_old;
// TODO: for PDEA/PDEP the constraint is tCLK, for SREFEN it is tXP
} else if (lastCmd == Command::PDXP || lastCmd == Command::PDXA) {
constraint = config.memSpec->tXP;
} else if (lastCmd == Command::SREFEX) {
constraint = config.memSpec->tXS;
// TODO: for PDEA/PDEP the constraint is tPRPDEN, for SREFEN the constraint is tRP
} else if (lastCmd == Command::PRE || lastCmd == Command::PREA) {
constraint = config.memSpec->tRP_old;
// TODO: ACT -> PDEA missing (tACTPDEN)
} else {
reportFatal("Powerdown checker",
commandToString(pdnCmd) + " can not follow " + commandToString(lastCmd));
}
return constraint;
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#ifndef POWERDOWNCHECKER_H
#define POWERDOWNCHECKER_H
#include <systemc>
#include "../../../ControllerState.h"
#include "../../configuration/Configuration.h"
#include "ICommandChecker.h"
class PowerDownChecker : public ICommandChecker
{
public:
PowerDownChecker(const Configuration &config,
ControllerState &state) : config(config), state(state) {}
virtual ~PowerDownChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const
override;
private:
const Configuration &config;
ControllerState &state;
sc_time getTimeConstraintToEnterPowerDown(Command lastCmd,
Command pdnCmd) const;
};
#endif // POWERDOWNCHECKER_H

View File

@@ -1,84 +0,0 @@
/*
* Copyright (c) 2017, 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: Éder F. Zulian
*/
#include "PreBChecker.h"
#include "../../timingCalculations.h"
void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const
{
sc_assert(cmd.getCommand() == Command::PREB);
ScheduledCommand lastCmd = state.getLastScheduledCommand(cmd.getBank());
if (lastCmd.isValidCommand()) {
// TODO: unused?
if (lastCmd.getCommand() == Command::PREB) {
cmd.establishMinDistanceFromStart(lastCmd.getStart(),
Configuration::getInstance().getTrpb());
} else if (lastCmd.getCommand() == Command::PRE) {
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRP_old);
} else if (lastCmd.getCommand() == Command::PREA) {
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRP_old);
// ------------
} else if (lastCmd.getCommand() == Command::ACTB) {
cmd.establishMinDistanceFromStart(lastCmd.getStart(),
config.memSpec->tRCD); // XXX: trcd is less than the NEW! trasb! ok!
} else if (lastCmd.getCommand() == Command::ACT) {
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRCD);
} else if (lastCmd.getCommand() == Command::RD) {
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRTP);
} else if (lastCmd.getCommand() == Command::WR) {
cmd.establishMinDistanceFromStart(lastCmd.getStart(),
config.memSpec->tWL + config.memSpec->getWriteAccessTime() + config.memSpec->tWR);
} else if (lastCmd.getCommand() == Command::PDXA) {
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tXP);
} else {
reportFatal("PreB Checker",
"PREB can not follow " + commandToString(lastCmd.getCommand()));
}
}
ScheduledCommand lc;
// TODO: unused?
if ((lc = state.getLastCommand(Command::PREA)).isValidCommand()) {
cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec->tRP_old);
}
// ------------
if ((lc = state.getLastCommandOnBank(Command::ACT,
cmd.getBank())).isValidCommand()) {
cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec->tRAS);
}
if ((lc = state.getLastCommandOnBank(Command::ACTB,
cmd.getBank())).isValidCommand()) {
cmd.establishMinDistanceFromStart(lc.getStart(),
Configuration::getInstance().getTrasb());
}
state.bus.moveCommandToNextFreeSlot(cmd);
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright (c) 2017, 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: Éder F. Zulian
*/
#ifndef PREBCHECKER_H
#define PREBCHECKER_H
#include "ICommandChecker.h"
#include "../../configuration/Configuration.h"
#include "../../../ControllerState.h"
class PreBChecker: public ICommandChecker
{
public:
PreBChecker(const Configuration &config,
ControllerState &state): config(config), state(state) {}
virtual ~PreBChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const
override;
private:
const Configuration &config;
ControllerState &state;
};
#endif // PREBCHECKER_H

View File

@@ -1,103 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
* Felipe S. Prado
*/
#include "PrechargeAllChecker.h"
#include "../../timingCalculations.h"
void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand &command)
const
{
sc_assert(command.getCommand() == Command::PREA);
// Consider all banks for the constraints, since precharge all command is supposed to happen at the same time on all banks
for (unsigned int bank = 0; bank < config.memSpec->NumberOfBanks; ++bank) {
ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank));
if (lastCommand.isValidCommand()) {
// TODO: Where do these dependencies come from?
if (lastCommand.getCommand() == Command::PRE
|| lastCommand.getCommand() == Command::PREB) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRP_old);
// TODO: Why tRCD and not tRAS?
} else if (lastCommand.getCommand() == Command::ACT
|| lastCommand.getCommand() == Command::ACTB) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRCD);
} else if (lastCommand.getCommand() == Command::RD) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRTP);
// TODO: missing
} else if (lastCommand.getCommand() == Command::RDA) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRTP + config.memSpec->tRP_old);
} else if (lastCommand.getCommand() == Command::WR) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tWL + config.memSpec->getWriteAccessTime() + config.memSpec->tWR);
// TODO: missing
} else if (lastCommand.getCommand() == Command::WRA) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tWL + config.memSpec->getWriteAccessTime() + config.memSpec->tWR +
config.memSpec->tRP_old);
} else if (lastCommand.getCommand() == Command::REFA) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRFC_old);
// TODO: PREA after PDXP possible?
} else if (lastCommand.getCommand() == Command::PDXA
|| lastCommand.getCommand() == Command::PDXP) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tXP);
} else if (lastCommand.getCommand() == Command::SREFEX) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tXS);
} else
reportFatal("Precharge All Checker",
"PREA can not follow " + commandToString(lastCommand.getCommand()));
}
}
ScheduledCommand lastActivate = state.getLastCommandOnBank(Command::ACT,
command.getBank());
// TODO: Why do we only check the ACT of one bank? (always bank 0)
if (lastActivate.isValidCommand()) {
command.establishMinDistanceFromStart(lastActivate.getStart(),
config.memSpec->tRAS);
}
state.bus.moveCommandToNextFreeSlot(command);
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
*/
#ifndef PRECHARGEALLCHECKER_H
#define PRECHARGEALLCHECKER_H
#include "ICommandChecker.h"
#include "../../configuration/Configuration.h"
#include "../../../ControllerState.h"
class PrechargeAllChecker: public ICommandChecker
{
public:
PrechargeAllChecker(const Configuration &config, ControllerState &state) :
config(config), state(state)
{
}
virtual ~PrechargeAllChecker()
{
}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const
override;
private:
const Configuration &config;
ControllerState &state;
};
#endif // PRECHARGEALLCHECKER_H

View File

@@ -1,87 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#include "PrechargeChecker.h"
#include "../../timingCalculations.h"
void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand &command)
const
{
//return;
sc_assert(command.getCommand() == Command::PRE);
ScheduledCommand lastCommand = state.getLastScheduledCommand(command.getBank());
if (lastCommand.isValidCommand()) {
// the first two cases happen when a resfresh interrups the command sequence of a transaction
// (e.g. commands to process transaction are PRE-ACT-RD and refresh happens after the PRE or after the ACT)
// TODO: unused?
if (lastCommand.getCommand() == Command::PRE
|| lastCommand.getCommand() == Command::PREB) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRP_old);
} else if (lastCommand.getCommand() == Command::ACT
|| lastCommand.getCommand() == Command::ACTB) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRCD);
}
// -------------
else if (lastCommand.getCommand() == Command::RD) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRTP);
} else if (lastCommand.getCommand() == Command::WR) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tWL + config.memSpec->getWriteAccessTime() + config.memSpec->tWR);
} else if (lastCommand.getCommand() == Command::PDXA) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tXP);
} else
reportFatal("Precharge Checker",
"PRE can not follow " + commandToString(lastCommand.getCommand()));
}
ScheduledCommand lastActivate = state.getLastCommandOnBank(Command::ACT,
command.getBank());
if (lastActivate.isValidCommand()) {
command.establishMinDistanceFromStart(lastActivate.getStart(),
config.memSpec->tRAS);
}
state.bus.moveCommandToNextFreeSlot(command);
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#ifndef PRECHARGECHECKER_H
#define PRECHARGECHECKER_H
#include "ICommandChecker.h"
#include "../../configuration/Configuration.h"
#include "../../../ControllerState.h"
class PrechargeChecker: public ICommandChecker
{
public:
PrechargeChecker(const Configuration &config,
ControllerState &state) : config(config), state(state) {}
virtual ~PrechargeChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const
override;
private:
const Configuration &config;
ControllerState &state;
};
#endif // PRECHARGECHECKER_

View File

@@ -1,146 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#include "ReadChecker.h"
#include "../../timingCalculations.h"
#include "../../../../common/utils.h"
#include "WriteChecker.h"
using namespace std;
void ReadChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
{
sc_assert(command.getCommand() == Command::RD
|| command.getCommand() == Command::RDA);
delayToSatisfyDLL(command);
ScheduledCommand lastCommand = state.getLastScheduledCommand(command.getBank());
if (lastCommand.isValidCommand()) {
if (lastCommand.getCommand() == Command::ACT
|| lastCommand.getCommand() == Command::ACTB) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRCD);
} else if (lastCommand.getCommand() == Command::RD) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
ReadChecker::readToRead(lastCommand, command));
} else if (lastCommand.getCommand() == Command::WR) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
ReadChecker::writeToRead(lastCommand, command));
} else if (/*lastCommand.getCommand() == Command::PDXP
|| */lastCommand.getCommand() == Command::PDXA) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tXP);
} else
reportFatal("Read Checker",
"RD/RDA can not follow " + commandToString(lastCommand.getCommand()));
}
while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe(command)) {
command.delayStart(config.memSpec->clk);
}
}
bool ReadChecker::collidesOnDataStrobe(ScheduledCommand &read) const
{
// for (ScheduledCommand &strobeCommand : state.lastDataStrobeCommands) {
// if (collidesWithStrobeCommand(read, strobeCommand))
// return true;
// }
return false;
}
bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand &read,
ScheduledCommand &strobeCommand) const
{
if (strobeCommand.getCommand() == Command::RD
|| strobeCommand.getCommand() == Command::RDA) {
return getDistance(read.getStart(),
strobeCommand.getStart()) < ReadChecker::readToRead(strobeCommand, read);
} else if (strobeCommand.getCommand() == Command::WR
|| strobeCommand.getCommand() == Command::WRA) {
if (strobeCommand.getStart() >= read.getStart())
return getDistance(read.getStart(),
strobeCommand.getStart()) < WriteChecker::readToWrite(read, strobeCommand);
else
return getDistance(strobeCommand.getStart(),
read.getStart()) < ReadChecker::writeToRead(strobeCommand, read);
} else {
reportFatal("Read Checker",
"Invalid strobeCommand in data strobe commands " + commandToString(
strobeCommand.getCommand()));
return true;
}
}
void ReadChecker::delayToSatisfyDLL(ScheduledCommand &read) const
{
ScheduledCommand lastSREFX = state.getLastCommandOnBank(Command::SREFEX,
read.getBank());
if (lastSREFX.isValidCommand())
read.establishMinDistanceFromStart(lastSREFX.getStart(),
config.memSpec->tXSDLL_old);
}
sc_time ReadChecker::readToRead(ScheduledCommand &firstRead,
ScheduledCommand &secondRead)
{
sc_assert(firstRead.getCommand() == Command::RD
|| firstRead.getCommand() == Command::RDA);
sc_assert(secondRead.getCommand() == Command::RD
|| secondRead.getCommand() == Command::RDA);
MemSpec *config = Configuration::getInstance().memSpec;
sc_time tCCD = (firstRead.getBankGroup() == secondRead.getBankGroup()) ?
config->tCCD_L_old : config->tCCD_S_old;
// TODO: When is tCCD smaller than readAccessTime?
return max(tCCD, config->getReadAccessTime());
}
sc_time ReadChecker::writeToRead(ScheduledCommand &write,
ScheduledCommand &read)
{
sc_assert(read.getCommand() == Command::RD
|| read.getCommand() == Command::RDA);
sc_assert(write.getCommand() == Command::WR
|| write.getCommand() == Command::WRA);
MemSpec *config = Configuration::getInstance().memSpec;
sc_time tWTR = (write.getBankGroup() == read.getBankGroup()) ? config->tWTR_L_old :
config->tWTR_S_old;
return config->tWL + config->getWriteAccessTime() + tWTR;
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#ifndef READCHECKER_H
#define READCHECKER_H
#include "ICommandChecker.h"
#include "../../configuration/Configuration.h"
#include "../../../ControllerState.h"
class ReadChecker: public ICommandChecker
{
public:
ReadChecker(Configuration &config, ControllerState &state) : config(config),
state(state) {}
virtual ~ReadChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const
override;
static sc_time readToRead(ScheduledCommand &firstRead,
ScheduledCommand &secondRead);
static sc_time writeToRead(ScheduledCommand &write, ScheduledCommand &read);
private:
const Configuration &config;
ControllerState &state;
void delayToSatisfyDLL(ScheduledCommand &read) const;
bool collidesOnDataStrobe(ScheduledCommand &read) const;
bool collidesWithStrobeCommand(ScheduledCommand &read,
ScheduledCommand &strobeCommand) const;
};
#endif // READCHECKER_H

View File

@@ -1,113 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
* Felipe S. Prado
*/
#include "RefreshChecker.h"
#include "../../timingCalculations.h"
void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
{
sc_assert(command.getCommand() == Command::REFA);
if (config.BankwiseLogic) {
ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(
command.getBank());
if (lastCommandOnBank.isValidCommand()) {
if (lastCommandOnBank.getCommand() == Command::PRE
|| lastCommandOnBank.getCommand() == Command::PREA) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tRP_old);
} else if (lastCommandOnBank.getCommand() == Command::RDA) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tRTP + config.memSpec->tRP_old);
} else if (lastCommandOnBank.getCommand() == Command::WRA) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tWL + config.memSpec->getWriteAccessTime() + config.memSpec->tWR +
config.memSpec->tRP_old);
} else if (lastCommandOnBank.getCommand() == Command::PDXP
|| lastCommandOnBank.getCommand() == Command::PDXA) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tXP);
} else if (lastCommandOnBank.getCommand() == Command::SREFEX) {
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
config.memSpec->tXS);
} else if (lastCommandOnBank.getCommand() == Command::REFA) {
} else
reportFatal("Refresh Checker",
"REFA can not follow " + commandToString(lastCommandOnBank.getCommand()));
}
} else {
for (unsigned int bank = 0; bank < config.memSpec->NumberOfBanks; ++bank) {
ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank));
if (lastCommand.isValidCommand()) {
if (lastCommand.getCommand() == Command::PRE
|| lastCommand.getCommand() == Command::PREA
|| lastCommand.getCommand() == Command::PREB) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRP_old);
} else if (lastCommand.getCommand() == Command::ACT
|| lastCommand.getCommand() == Command::ACTB) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRCD);
} else if (lastCommand.getCommand() == Command::RDA) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRTP + config.memSpec->tRP_old);
} else if (lastCommand.getCommand() == Command::WRA) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tWL + config.memSpec->getWriteAccessTime() + config.memSpec->tWR +
config.memSpec->tRP_old);
} else if (lastCommand.getCommand() == Command::PDXA
|| lastCommand.getCommand() == Command::PDXP) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tXP);
} else if (lastCommand.getCommand() == Command::SREFEX) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tXS);
} else if (lastCommand.getCommand() == Command::REFA) {
} else
reportFatal("Refresh Checker",
"Refresh can not follow " + commandToString(lastCommand.getCommand()));
}
}
}
state.bus.moveCommandToNextFreeSlot(command);
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#ifndef REFRESHCHECKER_H
#define REFRESHCHECKER_H
#include "ICommandChecker.h"
#include "../../../ControllerState.h"
#include "../../configuration/Configuration.h"
#include <systemc>
class RefreshChecker : public ICommandChecker
{
public:
RefreshChecker(const Configuration &config, ControllerState &state) :
config(config), state(state)
{
}
virtual ~RefreshChecker()
{
}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const
override;
private:
const Configuration &config;
ControllerState &state;
};
#endif // REFRESHCHECKER_H

View File

@@ -1,135 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#include "WriteChecker.h"
#include "../../timingCalculations.h"
#include "../../../../common/utils.h"
#include "ReadChecker.h"
using namespace std;
void WriteChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
{
sc_assert(command.getCommand() == Command::WR
|| command.getCommand() == Command::WRA);
ScheduledCommand lastCommand = state.getLastScheduledCommand(command.getBank());
if (lastCommand.isValidCommand()) {
if (lastCommand.getCommand() == Command::ACT
|| lastCommand.getCommand() == Command::ACTB) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tRCD);
} else if (lastCommand.getCommand() == Command::RD) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
WriteChecker::readToWrite(lastCommand, command));
} else if (lastCommand.getCommand() == Command::WR) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
WriteChecker::writeToWrite(lastCommand, command));
} else if (/*lastCommand.getCommand() == Command::PDXP
|| */lastCommand.getCommand() == Command::PDXA) {
command.establishMinDistanceFromStart(lastCommand.getStart(),
config.memSpec->tXP);
} else
reportFatal("Write Checker",
"WR/WRA can not follow " + commandToString(lastCommand.getCommand()));
}
while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe(command)) {
command.delayStart(config.memSpec->clk);
}
}
bool WriteChecker::collidesOnDataStrobe(ScheduledCommand &write) const
{
// for (ScheduledCommand &strobeCommand : state.lastDataStrobeCommands) {
// if (collidesWithStrobeCommand(write, strobeCommand))
// return true;
// }
return false;
}
bool WriteChecker::collidesWithStrobeCommand(ScheduledCommand &write,
ScheduledCommand &strobeCommand) const
{
if (strobeCommand.getCommand() == Command::WR
|| strobeCommand.getCommand() == Command::WRA) {
return getDistance(write.getStart(),
strobeCommand.getStart()) < WriteChecker::writeToWrite(strobeCommand, write);
} else if (strobeCommand.getCommand() == Command::RD
|| strobeCommand.getCommand() == Command::RDA) {
if (strobeCommand.getStart() >= write.getStart())
return getDistance(write.getStart(),
strobeCommand.getStart()) < ReadChecker::writeToRead(write, strobeCommand);
else
return getDistance(strobeCommand.getStart(),
write.getStart()) < WriteChecker::readToWrite(strobeCommand, write);
} else {
reportFatal("Write Checker",
"Invalid strobeCommand in data strobe commands " + commandToString(
strobeCommand.getCommand()));
return true;
}
}
sc_time WriteChecker::writeToWrite(ScheduledCommand &firstWrite,
ScheduledCommand &secondWrite)
{
sc_assert(firstWrite.getCommand() == Command::WR
|| firstWrite.getCommand() == Command::WRA);
sc_assert(secondWrite.getCommand() == Command::WR
|| secondWrite.getCommand() == Command::WRA);
MemSpec *config = Configuration::getInstance().memSpec;
sc_time tCCD = (firstWrite.getBankGroup() == secondWrite.getBankGroup()) ?
config->tCCD_L_old : config->tCCD_S_old;
// TODO: When is tCCD smaller than writeAccessTime?
return max(tCCD, config->getWriteAccessTime());
}
sc_time WriteChecker::readToWrite(ScheduledCommand &read __attribute__((
unused)), ScheduledCommand &write __attribute__((unused)))
{
sc_assert(read.getCommand() == Command::RD
|| read.getCommand() == Command::RDA);
sc_assert(write.getCommand() == Command::WR
|| write.getCommand() == Command::WRA);
MemSpec *config = Configuration::getInstance().memSpec;
return config->tRL + config->getReadAccessTime() - config->tWL + config->clk * 2;
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Matthias Jung
*/
#ifndef WRITECHECKER_H
#define WRITECHECKER_H
#include "ICommandChecker.h"
#include "../../configuration/Configuration.h"
#include "../../../ControllerState.h"
class WriteChecker : public ICommandChecker
{
public:
WriteChecker(const Configuration &config,
ControllerState &state) : config(config), state(state) {}
virtual ~WriteChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const
override;
static sc_time writeToWrite(ScheduledCommand &firstWrite,
ScheduledCommand &secondWrite);
static sc_time readToWrite(ScheduledCommand &read, ScheduledCommand &write);
private:
bool collidesOnDataStrobe(ScheduledCommand &write) const;
bool collidesWithStrobeCommand(ScheduledCommand &write,
ScheduledCommand &strobeCommand) const;
const Configuration &config;
ControllerState &state;
};
#endif // WRITECHECKER_H

View File

@@ -36,13 +36,10 @@
#include "timingCalculations.h"
#include "configuration/MemSpec.h"
#include "ControllerCore.h"
#include "../../common/DebugManager.h"
#include "configuration/Configuration.h"
#include "../../common/utils.h"
sc_time getDelayToMeetConstraint(sc_time previous, sc_time start,
sc_time constraint)
{

View File

@@ -35,12 +35,11 @@
#include "RefreshManager.h"
#include "../../common/dramExtensions.h"
#include "../core/configuration/Configuration.h"
#include "../../common/utils.h"
RefreshManager::RefreshManager()
{
// TODO: Change time of generation?
refreshPayload.set_extension(new GenerationExtension(SC_ZERO_TIME));
refreshPayload.set_extension(new DramExtension());
setUpDummy(refreshPayload);
memSpec = dynamic_cast<MemSpecDDR3 *>(Configuration::getInstance().memSpec);
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");

View File

@@ -1,70 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
*/
#include "Fifo.h"
void Fifo::storeRequest(gp *payload)
{
Bank bank = DramExtension::getExtension(payload).getBank();
buffer[bank].emplace_back(payload);
}
std::pair<Command, tlm::tlm_generic_payload *> Fifo::getNextRequest(Bank bank)
{
if (!buffer[bank].empty())
{
gp *payload = buffer[bank].front();
Command command = IScheduler::getNextCommand(payload);
if (command == Command::RD || command == Command::RDA
|| command == Command::WR || command == Command::WRA)
{
buffer[bank].pop_front();
}
return std::pair<Command, tlm::tlm_generic_payload *>(command, payload);
}
else
{
return std::pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
}
}
gp *Fifo::getPendingRequest(Bank /*bank*/)
{
return NULL;
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Robert Gernhardt
* Matthias Jung
*/
#ifndef FIFO_H
#define FIFO_H
#include <deque>
#include <map>
#include <utility>
#include "../core/ControllerCore.h"
#include "../Command.h"
#include "IScheduler.h"
class Fifo : public IScheduler
{
public:
Fifo(ControllerCore &controllerCore) : IScheduler(controllerCore) {}
virtual ~Fifo() {}
void storeRequest(gp *payload) override;
std::pair<Command, tlm::tlm_generic_payload *>
getNextRequest(Bank bank) override;
virtual gp *getPendingRequest(Bank bank) override;
private:
std::map<Bank, std::deque<gp *>> buffer;
};
#endif // FIFO_H

View File

@@ -1,136 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Éder F. Zulian
*/
#include "FifoStrict.h"
void FifoStrict::storeRequest(tlm::tlm_generic_payload *payload)
{
Bank bank = DramExtension::getExtension(payload).getBank();
buffer.push_back(std::pair<Bank, tlm::tlm_generic_payload *>(bank, payload));
}
std::pair<Command, tlm::tlm_generic_payload *> FifoStrict::getNextRequest(
Bank bank)
{
if (!buffer.empty()) {
if (buffer.front().first == bank) {
// The next request in the FIFO is for the bank passed as parameter
tlm::tlm_generic_payload *payload = buffer.front().second;
// For a given request (a given payload) one or more commands will
// be sent to the DRAM in order to process it.
//
// getNextRequest() may be called more than once for the same
// enqueued request until the appropriate sequence of commands is
// sent to the DRAM.
//
// Every time getNextRequest() is called it calls
// getNextCommand() that returns the suitable command to be sent
// to the DRAM.
//
// getNextCommand() returns the proper command based on the
// internal status of the DRAM.
//
// In the worst case getNextCommand() needs to be called three
// times for a given element in the requests queue: first for
// precharge, second for activate and finally for read or write
// (accordingly the nature of the request). In contrast, for the
// case of an already open row (due to a previous request) the
// command itself could be directly issued.
//
Command command = IScheduler::getNextCommand(payload);
if (commandIsIn(command, {Command::RD, Command::WR, Command::RDA, Command::WRA})) {
buffer.pop_front();
// Check if the next transaction is a blocked read or write
if (!buffer.empty()) {
tlm::tlm_generic_payload *p = buffer.front().second;
Command cmd = IScheduler::getNextCommand(p);
if (commandIsIn(cmd, {Command::RD, Command::WR, Command::RDA, Command::WRA})) {
Bank b = DramExtension::getBank(p);
controller.blockedRequests.push(b);
}
}
}
return std::pair<Command, tlm::tlm_generic_payload *>(command, payload);
} else {
// The next request in the FIFO is NOT for the bank passed as parameter.
// Search for the next request related to the bank passed as parameter.
for (auto req = buffer.begin(); req != buffer.end(); req++) {
if (req->first == bank) {
// Found a request to this bank in the queue
tlm::tlm_generic_payload *payload = req->second;
// Get the appropriate command to be sent to the DRAM
// regarding this request.
//
// Commands other than read and write will be issued.
// Reads and writes will not be issued since this
// scheduler executes all read and writes in a strict
// order.
Command command = getNextCommand(payload);
if (commandIsIn(command, {Command::RD, Command::WR, Command::RDA, Command::WRA})) {
// Reads and writes must be executed in order. Then if
// the next command for this request is read or write
// NOP will be returned and no operation will be
// performed.
return std::pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
}
else {
// Commands other than read and write are issued normally.
return std::pair<Command, tlm::tlm_generic_payload *>(command, payload);
}
}
}
}
}
return std::pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
}
gp *FifoStrict::getPendingRequest(Bank /*bank*/)
{
return NULL;
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Éder F. Zulian
*/
#ifndef FIFOSTRICT_H
#define FIFOSTRICT_H
#include <deque>
//#include <map>
#include <utility>
#include "../core/ControllerCore.h"
#include "../Command.h"
#include "IScheduler.h"
class FifoStrict : public IScheduler
{
public:
IController &controller;
FifoStrict(IController &controller, ControllerCore &controllerCore)
: IScheduler(controllerCore), controller(controller) {}
virtual ~FifoStrict() {}
void storeRequest(gp *payload) override;
std::pair<Command, tlm::tlm_generic_payload *>
getNextRequest(Bank bank) override;
virtual gp *getPendingRequest(Bank bank) override;
private:
std::deque<std::pair<Bank, tlm::tlm_generic_payload *>> buffer;
};
#endif // FIFOSTRICT_H

View File

@@ -1,122 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
//#include "FrFcfs.h"
//#include "../../common/dramExtensions.h"
//#include "../core/configuration/Configuration.h"
//#include <algorithm>
//using namespace std;
//// The FrFcfs (First Ready First Come First Served) is descibed in a 2000 paper from Rixner et al.:
//// Memory Access Scheduling
////
//// The FrFcfs scheduler features for each bank in the DRAM a specific
//// scheduling buffer for example:
////
//// Bank0: OOOOOOOO
//// Bank1: OOXXXXXX
//// ... ^ ^
//// ... | |
//// ... back |
//// ... front
//// ...
//// Bank6: OOOOO0XX
//// Bank7: XXXXXXXX
//void FrFcfs::storeRequest(gp *payload)
//{
// // FIXME: Question: what if the buffer is full? IMHO the schedule function
// // should provide a true or false when the placement into the buffer worked
// // out or not (?).
// buffer[DramExtension::getExtension(payload).getBank()]
// .emplace_back(payload);
//}
//std::pair<Command, gp *> FrFcfs::getNextRequest(Bank bank)
//{
// // If the bank is empty like Bank0 in the example we do nothing
// if (buffer[bank].empty())
// return std::pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
// // In FrFcfs row hits have always the highest priority, therefore we search
// // for row hits. If we find a row hit, we remove the transaction from the
// // queue and send it to the DRAM.
// std::deque<gp *>::iterator it = findRowHit(bank);
// if (it != buffer[bank].end())
// {
// gp *payload = *it;
// buffer[bank].erase(it);
// return std::pair<Command, gp *>(getReadWriteCommand(payload), payload);
// }
// // If there is no row hit, the FrFcfs takes always the oldest transaction
// // in the buffer, i.e. the transaction in the front.
// return std::pair<Command, gp *>(getNextCommand(buffer[bank].front()),
// buffer[bank].front());
//}
//// This function searches for a row hit in the scheduling queue of the specific
//// bank. If no row hit is found the end of the queue is returned.
////
//// Note: end() Returns an iterator referring to the past-the-end element in the
//// deque container. The past-the-end element is the theoretical element that
//// would follow the last element in the deque container. It does not point to
//// any element, and thus shall not be dereferenced.
//std::deque<gp *>::iterator FrFcfs::findRowHit(Bank bank)
//{
// std::deque<gp *> &queue = buffer[bank];
// Row activeRow = controllerCore.getRowBufferStates().getRowInRowBuffer(bank);
// if (!controllerCore.getRowBufferStates().rowBufferIsOpen(bank))
// return queue.end();
// // Traverse the scheduling queue of the specific bank:
// for (auto it = queue.begin(); it != queue.end(); it++)
// {
// //Found row-hit and return the according iterator
// if (DramExtension::getRow(*it) == activeRow)
// return it;
// }
// return queue.end();
//}
//gp *FrFcfs::getPendingRequest(Bank /*bank*/)
//{
// return NULL;
//}

View File

@@ -1,66 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef FRFCFS_H
#define FRFCFS_H
#include "IScheduler.h"
#include "../core/ControllerCore.h"
#include <list>
#include <map>
#include <vector>
class FrFcfs : public IScheduler
{
public:
FrFcfs(ControllerCore &controllerCore) : IScheduler(controllerCore) {}
virtual ~FrFcfs() {}
void storeRequest(gp *payload) override;
std::pair<Command, tlm::tlm_generic_payload *>
getNextRequest(Bank bank) override;
virtual gp *getPendingRequest(Bank bank) override;
protected:
std::map<Bank, std::deque<gp *>> buffer;
std::deque<gp *>::iterator findRowHit(Bank bank);
private:
};
#endif // FRFCFS_H

View File

@@ -1,194 +0,0 @@
/*
* Copyright (c) 2017, 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.
*
* Authors:
* Matthias Jung
*/
//#include "FrFcfsGrp.h"
//// The FrFcfsGrp (First Ready First Come First Served Grouper) works exactly
//// like the FrFcfsRp (First Ready First Come First Served Read Priority).
//// However writes are grouped! For detailed documentation look into the FrFcfs.
//// TODO: what is missed is a check if the buffers are full. This will only work
//// if we have buffers with a fixed size (Prado's future patch).
//std::pair<Command, gp *> FrFcfsGrp::getNextRequest(Bank bank)
//{
// // If the bank is empty we do nothing:
// if (buffer[bank].empty()) {
// return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
// }
// // If we are in write mode we should check if we should switch to read mode
// // because there are no writes anymore in the buffer.
// if (readMode == false) {
// if (getNumberOfRequest(tlm::TLM_WRITE_COMMAND) == 0) {
// readMode = true;
// }
// } else { // If we are in read mode but all reads are served we switch to write
// if (getNumberOfRequest(tlm::TLM_READ_COMMAND) == 0) {
// readMode = false;
// }
// }
// // Now lets search for read and write commands. However keep in mind that
// // readMode is a shared variable for all the banks!
// if (readMode == true) {
// // 1. Seach for read hit:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *read = *it;
// if (read->get_command() == tlm::TLM_READ_COMMAND) {
// // If there is a row hit:
// if (DramExtension::getRow(read)
// == controllerCore.getRowBufferStates()
// .getRowInRowBuffer(bank)) {
// if (hazardDetection(bank, it) == false) {
// buffer[bank].erase(it);
// printDebugMessage("Read Hit found");
// return pair<Command, gp *>(getReadWriteCommand(read),
// read);
// } else {
// // If there was a hazard, switch the mode and try again:
// readMode = false;
// return getNextRequest(bank);
// }
// }
// }
// }
// // 2. Search for read miss:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *read = *it;
// if (read->get_command() == tlm::TLM_READ_COMMAND) {
// if (hazardDetection(bank, it) == false) {
// printDebugMessage("Read miss found");
// return pair<Command, gp *>(getNextCommand(read), read);
// } else {
// // If there was a hazard, switch the mode and try again:
// readMode = false;
// return getNextRequest(bank);
// }
// }
// }
// } else { // write mode:
// // 3. Search for write hit:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *write = *it;
// if (write->get_command() == tlm::TLM_WRITE_COMMAND) {
// // If there is a row hit:
// if (DramExtension::getRow(write)
// == controllerCore.getRowBufferStates()
// .getRowInRowBuffer(bank)) {
// buffer[bank].erase(it);
// printDebugMessage("Write Hit found");
// return pair<Command, gp *>(getReadWriteCommand(write),
// write);
// }
// }
// }
// // 4. Search for write miss:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *write = *it;
// if (write->get_command() == tlm::TLM_WRITE_COMMAND) {
// printDebugMessage("Write miss found");
// return pair<Command, gp *>(getNextCommand(write), write);
// }
// }
// }
// // If nothing was found we check the other banks before we switch the mode:
// pair<Command, gp *> other(Command::NOP, NULL);
// unsigned int B = Configuration::getInstance().memSpec->NumberOfBanks;
// for (unsigned int i = 1; i < B; i++) {
// Bank nextBank((bank.ID() + i) % B);
// ctrl->scheduleNextFromScheduler(nextBank);
// }
// // If nothing was found in the current mode, switch the mode and try again:
// // FIXME: this is in my opinion not so clever yet, because we switch maybe
// // even though there are still reads/writes request on other banks ...
// readMode = !readMode;
// return getNextRequest(bank);
// reportFatal("FrFcfsGrp", "Never should go here ...");
//}
//// There is a hazard if a read is found which will be scheduled before a write
//// to the same column and the same row of the same bank:
//bool FrFcfsGrp::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
//{
// gp *read = *ext;
// //for(unsigned long i=0; i < id; i++)
// for (auto it = buffer[bank].begin(); it != ext; it++) {
// gp *write = *it;
// if (write->get_command() == tlm::TLM_WRITE_COMMAND) {
// if ((DramExtension::getExtension(read).getColumn()
// == DramExtension::getExtension(write).getColumn())
// && (DramExtension::getExtension(read).getRow()
// == DramExtension::getExtension(write).getRow())) {
// printDebugMessage("Hazard Detected");
// return true;
// }
// }
// }
// return false;
//}
//// Estimate the number of writes/reads in all bank buffers:
//unsigned int FrFcfsGrp::getNumberOfRequest(tlm::tlm_command cmd)
//{
// unsigned int numberOfRequests = 0;
// for (unsigned int i = 0;
// i < Configuration::getInstance().memSpec->NumberOfBanks;
// i++) {
// for (auto it = buffer[i].begin(); it != buffer[i].end(); it++) {
// gp *trans = *it;
// if (trans->get_command() == cmd) {
// numberOfRequests++;
// }
// }
// }
// return numberOfRequests;
//}
//void FrFcfsGrp::printDebugMessage(std::string message)
//{
// DebugManager::getInstance().printDebugMessage("FrFcfsGrp", message);
//}

View File

@@ -1,61 +0,0 @@
/*
* Copyright (c) 2017, 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.
*
* Authors:
* Matthias Jung
*/
#ifndef FRFCFSGRP_H
#define FRFCFSGRP_H
#include "FrFcfs.h"
#include "../Controller.h"
class Controller;
class FrFcfsGrp : public FrFcfs
{
public:
FrFcfsGrp(ControllerCore &controllerCore, Controller *c)
: FrFcfs(controllerCore), ctrl(c), readMode(true) {}
std::pair<Command, tlm::tlm_generic_payload *>
getNextRequest(Bank bank) override;
private:
Controller *ctrl;
bool hazardDetection(Bank bank, std::deque<gp *>::iterator ext);
unsigned int getNumberOfRequest(tlm::tlm_command cmd);
void printDebugMessage(std::string message);
bool readMode;
};
#endif // FRFCFSGRP_H

View File

@@ -1,140 +0,0 @@
/*
* Copyright (c) 2017, 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.
*
* Authors:
* Matthias Jung
*/
//#include "FrFcfsRp.h"
//// The FrFcfsRp (First Ready First Come First Served Read Priority) works
//// exactly like the FrFcfs but reads are prioratized over writes.
//// For detailed documentation look into the FrFcfs.
//std::pair<Command, gp *> FrFcfsRp::getNextRequest(Bank bank)
//{
// // If the bank is empty like Bank0 in the example we do nothing:
// if (buffer[bank].empty()) {
// return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
// }
// // Order of Priority:
// // 1. Read Hits (Hazard Check)
// // 2. Write Hits
// // 3. Read Miss (Hazard Check)
// // 4. Write Miss
// // 1. Seach for read hit:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *read = *it;
// if (read->get_command() == tlm::TLM_READ_COMMAND) {
// // If there is a row hit:
// if (DramExtension::getRow(read)
// == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) {
// if (hazardDetection(bank, it) == false) {
// buffer[bank].erase(it);
// printDebugMessage("Read Hit found");
// return pair<Command, gp *>(getReadWriteCommand(read), read);
// }
// }
// }
// }
// // 2. Search for write hit:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *write = *it;
// if (write->get_command() == tlm::TLM_WRITE_COMMAND) {
// // If there is a row hit:
// if (DramExtension::getRow(write)
// == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) {
// buffer[bank].erase(it);
// printDebugMessage("Write Hit found");
// return pair<Command, gp *>(getReadWriteCommand(write), write);
// }
// }
// }
// // For now return the oldest request but prefere also reads before writes:
// // 3. Search for read miss:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *read = *it;
// if (read->get_command() == tlm::TLM_READ_COMMAND) {
// if (hazardDetection(bank, it) == false) {
// printDebugMessage("Read miss found");
// return pair<Command, gp *>(getNextCommand(read), read);
// }
// }
// }
// // 3. Search for write miss:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *write = *it;
// if (write->get_command() == tlm::TLM_WRITE_COMMAND) {
// printDebugMessage("Write miss found");
// return pair<Command, gp *>(getNextCommand(write), write);
// }
// }
// reportFatal("FrFcfsRp", "Never should go here ...");
// return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
//}
//// There is a hazard if a read is found which will be scheduled before a write
//// to the same column and the same row of the same bank:
//bool FrFcfsRp::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
//{
// gp *read = *ext;
// //for(unsigned long i=0; i < id; i++)
// for (auto it = buffer[bank].begin(); it != ext; it++) {
// gp *write = *it;
// if (write->get_command() == tlm::TLM_WRITE_COMMAND) {
// if ((DramExtension::getExtension(read).getColumn()
// == DramExtension::getExtension(write).getColumn())
// && (DramExtension::getExtension(read).getRow()
// == DramExtension::getExtension(write).getRow())) {
// printDebugMessage("Hazard Detected");
// return true;
// }
// }
// }
// return false;
//}
//void FrFcfsRp::printDebugMessage(std::string message)
//{
// DebugManager::getInstance().printDebugMessage("FrFcfsRp", message);
//}

View File

@@ -1,53 +0,0 @@
/*
* Copyright (c) 2017, 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.
*
* Authors:
* Matthias Jung
*/
#ifndef FRFCFSRP_H
#define FRFCFSRP_H
#include "FrFcfs.h"
class FrFcfsRp : public FrFcfs
{
public:
FrFcfsRp(ControllerCore &controllerCore) : FrFcfs(controllerCore) {}
std::pair<Command, tlm::tlm_generic_payload *>
getNextRequest(Bank bank) override;
private:
bool hazardDetection(Bank bank, std::deque<gp *>::iterator ext);
void printDebugMessage(std::string message);
};
#endif // FRFCFSRP_H

View File

@@ -1,180 +0,0 @@
/*
* Copyright (c) 2018, 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.
*
* Authors:
* Matthias Jung
*/
//#include "Grp.h"
//// Grp (Grouper) just reorders w.r.t. read write grouping, however is not aware of the
//// row buffer. For a row buffer aware grouper refer to FrFcfsGrp.
//// TODO: what is missed is a check if the buffers are full. This will only work
//// if we have buffers with a fixed size (Prado's future patch).
//std::pair<Command, gp *> Grp::getNextRequest(Bank bank)
//{
// // If the bank is empty we do nothing:
// if (buffer[bank].empty()) {
// return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
// }
// // If we are in write mode we should check if we should switch to read mode
// // because there are no writes anymore in the buffer.
// if (readMode == false) {
// if (getNumberOfRequest(tlm::TLM_WRITE_COMMAND) == 0) {
// readMode = true;
// }
// } else { // If we are in read mode but all reads are served we switch to write
// if (getNumberOfRequest(tlm::TLM_READ_COMMAND) == 0) {
// readMode = false;
// }
// }
// // Now lets search for read and write commands. However keep in mind that
// // readMode is a shared variable for all the banks!
// if (readMode == true) {
// // 1. Seach for read hit:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *read = *it;
// if (read->get_command() == tlm::TLM_READ_COMMAND) {
// // If there is a row hit:
// if (DramExtension::getRow(read)
// == controllerCore.getRowBufferStates()
// .getRowInRowBuffer(bank)) {
// if (hazardDetection(bank, it) == false) {
// buffer[bank].erase(it);
// printDebugMessage("Read Hit found");
// return pair<Command, gp *>(getReadWriteCommand(read),
// read);
// } else {
// // If there was a hazard, switch the mode and try again:
// readMode = false;
// return getNextRequest(bank);
// }
// } else { // if there is a row miss:
// if (hazardDetection(bank, it) == false) {
// printDebugMessage("Read miss found");
// return pair<Command, gp *>(getNextCommand(read), read);
// } else {
// // If there was a hazard, switch the mode and try again:
// readMode = false;
// return getNextRequest(bank);
// }
// }
// }
// }
// } else { // write mode:
// // 3. Search for write hit:
// for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) {
// gp *write = *it;
// if (write->get_command() == tlm::TLM_WRITE_COMMAND) {
// // If there is a row hit:
// if (DramExtension::getRow(write)
// == controllerCore.getRowBufferStates()
// .getRowInRowBuffer(bank)) {
// buffer[bank].erase(it);
// printDebugMessage("Write Hit found");
// return pair<Command, gp *>(getReadWriteCommand(write),
// write);
// } else {
// printDebugMessage("Write miss found");
// return pair<Command, gp *>(getNextCommand(write), write);
// }
// }
// }
// }
// // If nothing was found we check the other banks before we switch the mode:
// pair<Command, gp *> other(Command::NOP, NULL);
// unsigned int B = Configuration::getInstance().memSpec->NumberOfBanks;
// for (unsigned int i = 1; i < B; i++) {
// Bank nextBank((bank.ID() + i) % B);
// ctrl->scheduleNextFromScheduler(nextBank);
// }
// // If nothing was found in the current mode, switch the mode and try again:
// // FIXME: this is in my opinion not so clever yet, because we switch maybe
// // even though there are still reads/writes request on other banks ...
// readMode = !readMode;
// return getNextRequest(bank);
// reportFatal("Grp", "Never should go here ...");
//}
//// There is a hazard if a read is found which will be scheduled before a write
//// to the same column and the same row of the same bank:
//bool Grp::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
//{
// gp *read = *ext;
// //for(unsigned long i=0; i < id; i++)
// for (auto it = buffer[bank].begin(); it != ext; it++) {
// gp *write = *it;
// if (write->get_command() == tlm::TLM_WRITE_COMMAND) {
// if ((DramExtension::getExtension(read).getColumn()
// == DramExtension::getExtension(write).getColumn())
// && (DramExtension::getExtension(read).getRow()
// == DramExtension::getExtension(write).getRow())) {
// printDebugMessage("Hazard Detected");
// return true;
// }
// }
// }
// return false;
//}
//// Estimate the number of writes/reads in all bank buffers:
//unsigned int Grp::getNumberOfRequest(tlm::tlm_command cmd)
//{
// unsigned int numberOfRequests = 0;
// for (unsigned int i = 0;
// i < Configuration::getInstance().memSpec->NumberOfBanks;
// i++) {
// for (auto it = buffer[i].begin(); it != buffer[i].end(); it++) {
// gp *trans = *it;
// if (trans->get_command() == cmd) {
// numberOfRequests++;
// }
// }
// }
// return numberOfRequests;
//}
//void Grp::printDebugMessage(std::string message)
//{
// DebugManager::getInstance().printDebugMessage("FrFcfsGrp", message);
//}

View File

@@ -1,61 +0,0 @@
/*
* Copyright (c) 2018, 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.
*
* Authors:
* Matthias Jung
*/
#ifndef GRP_H
#define GRP_H
#include "FrFcfs.h"
#include "../Controller.h"
class Controller;
class Grp : public FrFcfs
{
public:
Grp(ControllerCore &controllerCore, Controller *c)
: FrFcfs(controllerCore), ctrl(c), readMode(true) {}
std::pair<Command, tlm::tlm_generic_payload *>
getNextRequest(Bank bank) override;
private:
Controller *ctrl;
bool hazardDetection(Bank bank, std::deque<gp *>::iterator ext);
unsigned int getNumberOfRequest(tlm::tlm_command cmd);
void printDebugMessage(std::string message);
bool readMode;
};
#endif // GRP_H

View File

@@ -1,96 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
//#include "IScheduler.h"
//#include "../../common/DebugManager.h"
//#include "../core/configuration/Configuration.h"
//std::string IScheduler::sendername = "scheduler";
//void IScheduler::printDebugMessage(std::string message)
//{
// DebugManager::getInstance().printDebugMessage(IScheduler::sendername, message);
//}
//// Get the next command that is necessary to process the request representend by the payload
//Command IScheduler::getNextCommand(gp &payload)
//{
// Bank bank = DramExtension::getBank(payload);
// if (!controllerCore.getRowBufferStates().rowBufferIsOpen(bank))
// {
// return Command::ACT;
// }
// else if (controllerCore.getRowBufferStates().rowBufferIsOpen(bank) &&
// controllerCore.getRowBufferStates().getRowInRowBuffer(bank) !=
// DramExtension::getRow(payload))
// {
// return Command::PRE;
// }
// else
// {
// return getReadWriteCommand(payload);
// }
//}
//Command IScheduler::getNextCommand(gp *payload)
//{
// return getNextCommand(*payload);
//}
//Command IScheduler::getReadWriteCommand(gp &payload)
//{
// if (payload.get_command() == tlm::TLM_READ_COMMAND)
// {
// if (Configuration::getInstance().OpenPagePolicy)
// return Command::RD;
// else
// return Command::RDA;
// }
// else
// {
// if (Configuration::getInstance().OpenPagePolicy)
// return Command::WR;
// else
// return Command::WRA;
// }
//}
//Command IScheduler::getReadWriteCommand(gp *payload)
//{
// return getReadWriteCommand(*payload);
//}

View File

@@ -1,70 +0,0 @@
/*
* Copyright (c) 2015, 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.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef ISCHEDULER_H
#define ISCHEDULER_H
#include <tlm.h>
#include "../../common/dramExtensions.h"
#include "../Command.h"
#include "../core/ControllerCore.h"
typedef tlm::tlm_generic_payload gp;
class IScheduler
{
public:
virtual ~IScheduler() {}
IScheduler(ControllerCore &controllerCore) : controllerCore(controllerCore) {}
virtual void storeRequest(gp *payload) = 0;
virtual std::pair<Command, gp *> getNextRequest(Bank bank) = 0;
virtual gp *getPendingRequest(Bank bank) = 0;
static std::string sendername;
protected:
void printDebugMessage(std::string message);
Command getNextCommand(gp &payload);
Command getNextCommand(gp *payload);
Command getReadWriteCommand(gp &payload);
Command getReadWriteCommand(gp *payload);
ControllerCore &controllerCore;
};
#endif // ISCHEDULER_H

View File

@@ -1,358 +0,0 @@
#include "SMS.h"
#include <random>
using namespace std;
void SMS::storeRequest(gp *payload)
{
Thread thread = DramExtension::getExtension(payload).getThread();
bool wasEmpty = isRequestBuffersEmpty();
requestBuffers[thread].emplace_back(payload);
if (inFlightMemRequestCounter.find(thread) == inFlightMemRequestCounter.end()) {
inFlightMemRequestCounter[thread] = 0;
cacheMisses[thread] = 0;
}
inFlightMemRequestCounter[thread]++;
cacheMisses[thread]++;
if (wasEmpty) {
newRequest.notify(SC_ZERO_TIME);
}
}
std::pair<Command, gp *> SMS::getNextRequest(Bank bank)
{
if (bankBuffers[bank].empty()) {
debugManager.printDebugMessage(name(),
"Get next request on bank " + to_string(bank.ID()) + " : EMPTY buffer");
return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
} else {
gp *payload = bankBuffers[bank].front();
Command command = IScheduler::getNextCommand(payload);
if (command == Command::RD || command == Command::RDA
|| command == Command::WR
|| command == Command::WRA) {
inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]--;
bankBuffers[bank].pop_front();
}
debugManager.printDebugMessage(name(),
"Get next request on bank " + to_string(bank.ID()));
return pair<Command, tlm::tlm_generic_payload *>(command, payload);
}
}
void SMS::batchScheduler()
{
sc_time memClk = Configuration::getInstance().memSpec->clk;
std::default_random_engine generator;
std::bernoulli_distribution distribution((double) SJFprobability / 100.0);
while (true) {
updateMPKCs(memClk);
if (isRequestBuffersEmpty()) {
wait(newRequest);
} else {
multiBatchFormation(memClk);
if (existReadyBatches()) {
if (!isSystemLightlyLoaded() && (existLowIntensityThread()
|| distribution(generator))) {
pickSJF();
} else {
pickRR();
}
drainOnePayloadFromReadybatch(memClk);
} else {
wait(memClk);
}
}
}
}
/**
* Pick a Thread according to Shortest-Job Policy
* Save the picked one into lastSelectedThread
* @return true if it can, otherwise false
*/
bool SMS::pickSJF()
{
// find threads with ready batches
std::vector<Thread> threadsWithReadyBatches;
for (const auto &each : readyBatchInclusiveEndLocs) {
if (!each.second.empty()) {
// marked as thread with non-empty request buffer
threadsWithReadyBatches.push_back(each.first);
}
}
if (!threadsWithReadyBatches.empty()) {
// pick shortest-job thread among threads with non-empty request buffer
Thread &minThread = threadsWithReadyBatches.front();
for (const auto &thread : threadsWithReadyBatches) {
if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) {
minThread = thread;
}
}
// save selected thread
lastSelectedThread = readyBatchInclusiveEndLocs.find(minThread);
debugManager.printDebugMessage(name(),
"[SJF] Select ready batch of thread " + to_string(minThread.ID()));
return true;
} else {
return false;
}
}
/**
* Drain the picked request buffer into bank buffers
* by move request one-by-one from start of the request buffer till last parameter
* @param memClk
* @param last
*/
void SMS::drainOnePayloadFromReadybatch(const sc_time &memClk)
{
if (lastSelectedThread->second.empty()) {
return;
}
const Thread &selectedThread = lastSelectedThread->first;
const size_t &inclusiveEndLoc = lastSelectedThread->second.front();
assert(inclusiveEndLoc < requestBuffers.size());
for (size_t i = 0; i <= inclusiveEndLoc; ++i) {
wait(memClk);
Bank bank = DramExtension::getExtension(
requestBuffers[selectedThread].front()).getBank();
bankBuffers[bank].emplace_back(requestBuffers[selectedThread].front());
requestBuffers[selectedThread].pop_front();
// decrement inclusive end locations of ready batches
// except this ready batch
for (size_t i = 1; i < readyBatchInclusiveEndLocs[selectedThread].size(); ++i) {
--readyBatchInclusiveEndLocs[selectedThread][i];
}
debugManager.printDebugMessage(name(),
"[SJF] Drain request in the ready batch of thread "
+ to_string((*lastSelectedThread).first.ID()) + " to bankbuffer "
+ to_string(bank.ID()));
}
lastSelectedThread->second.pop_front();
}
/**
* Pick a Thread according to Round-Robin Policy
* Save the picked one into lastSelectedThread
* @return true if it can pick one, otherwise false
*/
bool SMS::pickRR()
{
if (lastSelectedThread == readyBatchInclusiveEndLocs.end()) {
lastSelectedThread = readyBatchInclusiveEndLocs.begin();
if (!(*lastSelectedThread).second.empty()) {
return true;
}
}
std::map<Thread, std::deque<size_t>>::iterator savedOriginalNextSelectedThread =
lastSelectedThread;
do {
lastSelectedThread++;
if (lastSelectedThread == readyBatchInclusiveEndLocs.end()) {
lastSelectedThread = readyBatchInclusiveEndLocs.begin();
}
if (lastSelectedThread == savedOriginalNextSelectedThread) {
return false;
}
} while ((*lastSelectedThread).second.empty());
debugManager.printDebugMessage(name(),
"[RR] Select ready batch of thread " + to_string((
*lastSelectedThread).first.ID()));
return true;
}
bool SMS::isSystemLightlyLoaded() const
{
unsigned int totalRequest = 0;
for (const auto &bankBuffer : bankBuffers) {
totalRequest += bankBuffer.second.size();
}
return (totalRequest <= LOW_SYSTEM_LOAD);
}
bool SMS::existLowIntensityThread() const
{
for (const auto &mpkcPerThread : MPKCs) {
if (mpkcPerThread.second < LOW_MPKC) {
return true;
}
}
return false;
}
bool SMS::isThresholdAgeExceeded(const Thread &thread, sc_time const &memClk,
size_t const &inclusiveBeginLoc, size_t const &exclusiveEndLoc)
{
assert((exclusiveEndLoc - inclusiveBeginLoc) >= 1);
// find the oldest request in the thread's batch
sc_time oldestGenerationTime = sc_time_stamp();
for (size_t i = inclusiveBeginLoc; i != exclusiveEndLoc; ++i) {
sc_time reqGenerationTime = GenerationExtension::getExtension(
requestBuffers[thread][i]).TimeOfGeneration();
if (reqGenerationTime < oldestGenerationTime) {
oldestGenerationTime = reqGenerationTime;
}
}
// check threshold age according to the thread's MPKC
sc_time oldestRequestAge = sc_time_stamp() - oldestGenerationTime;
if ((MPKCs[thread] <= MEDIUM_MPKC)
&& (oldestRequestAge > (MEDIUM_THRESHOLD_AGE * memClk))) {
return true;
} else if ((MPKCs[thread] > MEDIUM_MPKC)
&& (oldestRequestAge > (HIGH_THRESHOLD_AGE * memClk))) {
return true;
} else {
return false;
}
}
void SMS::updateMPKCs(sc_time const &memClk)
{
if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) {
// reset for every 10k clk cycles
for (const auto &cacheMiss : cacheMisses) {
MPKCs[cacheMiss.first] = 0;
}
debugManager.printDebugMessage(name(), "Reset MKKCs");
} else {
// update MPKC for every thread
for (const auto &cacheMiss : cacheMisses) {
MPKCs[cacheMiss.first] = (cacheMiss.second * 1000.0 * memClk) /
(sc_time_stamp());
}
debugManager.printDebugMessage(name(), "Update MPKCs");
}
}
bool SMS::isExceededReqBufferSize(size_t const &exclusiveEndLoc)
{
return exclusiveEndLoc <= Configuration::getInstance().RequestBufferSize;
}
bool SMS::isRequestBuffersEmpty() const
{
for (const auto &requestBuffer : requestBuffers) {
if (!requestBuffer.second.empty()) {
return false;
}
}
return true;
}
bool SMS::existReadyBatches() const
{
for (const auto &each : readyBatchInclusiveEndLocs) {
if (!each.second.empty()) {
return true;
}
}
return false;
}
/**
* Form batch from begin iterator parameter of a request buffer
* If this batch is deemed ready, save the iterator pointing to its last element
* @param memClk
* @param begin
* @return true if this batch is ready, otherwise false
*/
bool SMS::batchFormation(sc_time const &memClk, Thread const &thread,
std::deque<gp *> const &requestBuffer, size_t const &inclusiveBeginLoc)
{
if (requestBuffer.empty()) {
return false;
}
assert(inclusiveBeginLoc <= requestBuffer.size());
if (requestBuffer.size() == inclusiveBeginLoc) {
return false;
}
if (MPKCs[thread] < LOW_MPKC || isSystemLightlyLoaded()) {
// bypass requests by forming batch with only one request (threshold age is ZERO)
readyBatchInclusiveEndLocs[thread].push_back(inclusiveBeginLoc);
return true;
} else {
// forming batch with FIFO size & threshold age constraints
size_t firstDifferentRowAccessReqLoc = inclusiveBeginLoc;
Row firstRow = DramExtension::getRow(requestBuffer[inclusiveBeginLoc]);
bool isBatchReady = false;
size_t bufferSize = requestBuffer.size();
while (firstDifferentRowAccessReqLoc != bufferSize
&& DramExtension::getRow(requestBuffer[firstDifferentRowAccessReqLoc]) ==
firstRow) {
++firstDifferentRowAccessReqLoc;
if (firstDifferentRowAccessReqLoc < bufferSize) {
if (DramExtension::getRow(requestBuffer[firstDifferentRowAccessReqLoc]) !=
firstRow
|| isExceededReqBufferSize(firstDifferentRowAccessReqLoc)
|| isThresholdAgeExceeded(thread, memClk, inclusiveBeginLoc,
firstDifferentRowAccessReqLoc)) {
isBatchReady = true;
break;
}
} else {
if (isExceededReqBufferSize(firstDifferentRowAccessReqLoc)
|| isThresholdAgeExceeded(thread, memClk, inclusiveBeginLoc,
firstDifferentRowAccessReqLoc)) {
isBatchReady = true;
break;
}
}
}
// store this ready batch location
if (isBatchReady) {
--firstDifferentRowAccessReqLoc;
readyBatchInclusiveEndLocs[thread].push_back(firstDifferentRowAccessReqLoc);
debugManager.printDebugMessage(name(),
"Deem batch ready - thread " + to_string(thread.ID()));
return true;
} else {
return false;
}
}
}
void SMS::multiBatchFormation(sc_time const &memClk)
{
for (auto &requestBuffer : requestBuffers) {
bool formed = false;
do {
if (readyBatchInclusiveEndLocs[requestBuffer.first].empty()) {
formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, 0);
} else {
formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second,
readyBatchInclusiveEndLocs[requestBuffer.first].back() + 1);
}
} while (!requestBuffer.second.empty() && formed);
}
}
gp *SMS::getPendingRequest(Bank bank)
{
for (const auto &requestBuffer : requestBuffers) {
for (const auto &request : requestBuffer.second) {
if (DramExtension::getBank(request) == bank) {
return request;
}
}
}
return NULL;
}

View File

@@ -1,88 +0,0 @@
#ifndef SMS_H
#define SMS_H
#include <stdlib.h>
#include <time.h>
#include "sysc/utils/sc_report.h"
#include "IScheduler.h"
#include "../core/ControllerCore.h"
#include "../core/configuration/Configuration.h"
#include "../../common/dramExtensions.h"
#include "../../common/DebugManager.h"
#define LOW_SYSTEM_LOAD 16
#define LOW_MPKC 1
#define MEDIUM_MPKC 10
#define MEDIUM_THRESHOLD_AGE 50
#define HIGH_THRESHOLD_AGE 200
#define MPKC_RESET_CYCLE 10000
using namespace std;
typedef std::deque<gp *>::iterator gp_deque_iterator;
/**
* SMS - Staged Memory Scheduler involves 3 steps:
* 1. Arrage request in to each buffer of each thread
* 2. Forming ready batches for each thread, i.e all requests access the same row. The batch is deemed
* ready when the next request accesses different row OR When the buffer is full OR When this batch
* is too old
* 3. Send batches to bank buffers. The rules to send batches are Shortest-Job-First OR Round-Robin
* How we select the rule depends on the probability we setup earlier.
*/
class SMS: public sc_module, public IScheduler
{
public:
SMS(sc_module_name /*_name*/, ControllerCore &controllerCore,
unsigned int SJFprobability) : IScheduler(controllerCore),
SJFprobability(SJFprobability), debugManager(DebugManager::getInstance())
{
// initialize selected thread iterator
lastSelectedThread = readyBatchInclusiveEndLocs.end();
SC_THREAD(batchScheduler);
}
SC_HAS_PROCESS(SMS);
virtual ~SMS()
{
}
virtual void storeRequest(gp *payload) override;
virtual std::pair<Command, gp *> getNextRequest(Bank bank) override;
virtual gp *getPendingRequest(Bank bank) override;
void batchScheduler();
private:
std::map<Thread, std::deque<gp *>> requestBuffers;
std::map<Bank, std::deque<gp *>> bankBuffers;
std::map<Thread, std::deque<size_t>> readyBatchInclusiveEndLocs;
std::map<Thread, unsigned int> inFlightMemRequestCounter;
std::map<Thread, unsigned int> cacheMisses;
std::map<Thread, float> MPKCs;
unsigned int SJFprobability;
std::map<Thread, std::deque<size_t>>::iterator lastSelectedThread;
sc_event newRequest;
DebugManager &debugManager;
bool batchFormation(sc_time const &memClk, Thread const &thread,
const std::deque<gp *> &requestBuffer, const size_t &inclusiveBeginLoc);
void multiBatchFormation(const sc_time &memClk);
bool pickSJF();
bool pickRR();
void drainOnePayloadFromReadybatch(const sc_time &memClk);
bool existLowIntensityThread() const;
bool isSystemLightlyLoaded() const;
bool isThresholdAgeExceeded(const Thread &thread, const sc_time &memClk,
const size_t &inclusiveBeginLoc, const size_t &exclusiveEndLoc);
bool isExceededReqBufferSize(size_t const &exclusiveEndLoc);
void updateMPKCs(const sc_time &memClk);
bool isRequestBuffersEmpty() const;
bool existReadyBatches() const;
};
#endif // SMS_H

View File

@@ -48,11 +48,9 @@
#include "../common/DebugManager.h"
#include "../common/XmlAddressDecoder.h"
#include "../common/CongenAddressDecoder.h"
#include "../controller/core/ControllerCore.h"
#include "../controller/core/configuration/ConfigurationLoader.h"
#include "../common/utils.h"
#include "../simulation/TemperatureController.h"
#include "../controller/Controller.h"
#include "../error/ecchamming.h"
#include "DramRecordable.h"
#include "DramDDR3.h"

View File

@@ -48,7 +48,6 @@
#include "ReorderBuffer.h"
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include "../controller/RecordableController.h"
#include "../common/third_party/tinyxml2/tinyxml2.h"
#include "../common/tlm2_base_protocol_checker.h"
#include "../error/eccbaseclass.h"

View File

@@ -50,7 +50,6 @@
#include <stdlib.h>
#include "../common/DebugManager.h"
#include "../common/dramExtensions.h"
#include "../controller/Controller.h"
#include "../controller/core/timingCalculations.h"
#include "../controller/core/configuration/Configuration.h"
#include "../common/protocol.h"