Merge branch 'DRAMSys4.0_ctrl' into controller_improvements
This commit is contained in:
@@ -47,90 +47,116 @@ set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ Version")
|
||||
set(DCMAKE_SH="CMAKE_SH-NOTFOUND")
|
||||
|
||||
include_directories(
|
||||
src/simulation
|
||||
src/simulation/dram
|
||||
src/controller
|
||||
src/controller/checker
|
||||
src/controller/cmdmux
|
||||
src/controller/powerdown
|
||||
src/controller/refresh
|
||||
src/controller/scheduler
|
||||
src/common
|
||||
src/common/third_party/DRAMPower/src
|
||||
src/configuration
|
||||
src/configuration/memspec
|
||||
src/error
|
||||
src/error/ECC
|
||||
src/common
|
||||
src/common/third_party/DRAMPower/src
|
||||
src/configuration
|
||||
src/configuration/memspec
|
||||
src/controller
|
||||
src/controller/checker
|
||||
src/controller/cmdmux
|
||||
src/controller/powerdown
|
||||
src/controller/refresh
|
||||
src/controller/respqueue
|
||||
src/controller/scheduler
|
||||
src/error
|
||||
src/error/ECC
|
||||
src/simulation
|
||||
src/simulation/dram
|
||||
)
|
||||
|
||||
add_library(DRAMSysLibrary
|
||||
src/common/third_party/tinyxml2/tinyxml2.cpp
|
||||
src/common/TlmRecorder.cpp
|
||||
src/common/DebugManager.cpp
|
||||
src/configuration/Configuration.cpp
|
||||
src/simulation/MemoryManager.cpp
|
||||
src/simulation/TemperatureController.cpp
|
||||
src/configuration/ConfigurationLoader.cpp
|
||||
src/controller/Command.cpp
|
||||
src/error/errormodel.cpp
|
||||
src/simulation/TracePlayer.cpp
|
||||
src/simulation/TraceSetup.cpp
|
||||
src/simulation/DRAMSys.cpp
|
||||
src/simulation/Setup.cpp
|
||||
src/error/ECC/Bit.cpp
|
||||
src/error/ECC/ECC.cpp
|
||||
src/error/ECC/Word.cpp
|
||||
src/error/eccbaseclass.cpp
|
||||
src/error/ecchamming.cpp
|
||||
src/common/AddressDecoder.cpp
|
||||
src/simulation/dram/Dram.cpp
|
||||
src/simulation/Arbiter.cpp
|
||||
src/common/CongenAddressDecoder.cpp
|
||||
src/common/XmlAddressDecoder.cpp
|
||||
src/common/timingCalculations.cpp
|
||||
src/common/dramExtensions.cpp
|
||||
src/common/utils.cpp
|
||||
src/simulation/dram/DramDDR3.cpp
|
||||
src/simulation/dram/DramDDR4.cpp
|
||||
src/simulation/dram/DramRecordable.cpp
|
||||
src/simulation/dram/DramWideIO.cpp
|
||||
src/configuration/memspec/MemSpec.cpp
|
||||
src/controller/BankMachine.cpp
|
||||
src/controller/Controller.cpp
|
||||
src/controller/scheduler/SchedulerFifo.cpp
|
||||
src/controller/scheduler/SchedulerFrFcfs.cpp
|
||||
src/controller/cmdmux/CmdMuxStrict.cpp
|
||||
src/controller/cmdmux/CmdMuxOldest.cpp
|
||||
src/controller/ControllerRecordable.cpp
|
||||
src/controller/checker/CheckerDDR3.cpp
|
||||
src/controller/refresh/RefreshManager.cpp
|
||||
src/controller/refresh/RefreshManagerDummy.cpp
|
||||
src/controller/refresh/RefreshManagerBankwise.cpp
|
||||
src/controller/checker/CheckerWideIO.cpp
|
||||
src/configuration/memspec/MemSpecDDR3.cpp
|
||||
src/configuration/memspec/MemSpecDDR4.cpp
|
||||
src/configuration/memspec/MemSpecWideIO.cpp
|
||||
src/configuration/memspec/MemSpecLPDDR4.cpp
|
||||
src/controller/checker/CheckerDDR4.cpp
|
||||
src/simulation/dram/DramLPDDR4.cpp
|
||||
src/controller/checker/CheckerLPDDR4.cpp
|
||||
src/configuration/memspec/MemSpecWideIO2.cpp
|
||||
src/simulation/dram/DramWideIO2.cpp
|
||||
src/controller/checker/CheckerWideIO2.cpp
|
||||
src/configuration/memspec/MemSpecHBM2.cpp
|
||||
src/simulation/dram/DramHBM2.cpp
|
||||
src/controller/checker/CheckerHBM2.cpp
|
||||
src/configuration/memspec/MemSpecGDDR5.cpp
|
||||
src/configuration/memspec/MemSpecGDDR5X.cpp
|
||||
src/configuration/memspec/MemSpecGDDR6.cpp
|
||||
src/controller/checker/CheckerGDDR5.cpp
|
||||
src/controller/checker/CheckerGDDR5X.cpp
|
||||
src/controller/checker/CheckerGDDR6.cpp
|
||||
src/simulation/dram/DramGDDR5.cpp
|
||||
src/simulation/dram/DramGDDR5X.cpp
|
||||
src/simulation/dram/DramGDDR6.cpp
|
||||
src/controller/powerdown/PowerDownManagerStaggered.cpp
|
||||
src/controller/powerdown/PowerDownManagerDummy.cpp
|
||||
src/common/third_party/tinyxml2/tinyxml2.cpp
|
||||
src/common/TlmRecorder.cpp
|
||||
src/common/DebugManager.cpp
|
||||
src/common/CongenAddressDecoder.cpp
|
||||
src/common/XmlAddressDecoder.cpp
|
||||
src/common/timingCalculations.cpp
|
||||
src/common/dramExtensions.cpp
|
||||
src/common/utils.cpp
|
||||
src/common/AddressDecoder.cpp
|
||||
src/common/protocol.h
|
||||
src/common/tlm2_base_protocol_checker.h
|
||||
|
||||
src/configuration/Configuration.cpp
|
||||
src/configuration/ConfigurationLoader.cpp
|
||||
src/configuration/TemperatureSimConfig.h
|
||||
|
||||
src/configuration/memspec/MemSpec.cpp
|
||||
src/configuration/memspec/MemSpecDDR3.cpp
|
||||
src/configuration/memspec/MemSpecDDR4.cpp
|
||||
src/configuration/memspec/MemSpecLPDDR4.cpp
|
||||
src/configuration/memspec/MemSpecWideIO.cpp
|
||||
src/configuration/memspec/MemSpecWideIO2.cpp
|
||||
src/configuration/memspec/MemSpecGDDR5.cpp
|
||||
src/configuration/memspec/MemSpecGDDR5X.cpp
|
||||
src/configuration/memspec/MemSpecGDDR6.cpp
|
||||
src/configuration/memspec/MemSpecHBM2.cpp
|
||||
|
||||
src/controller/BankMachine.cpp
|
||||
src/controller/Command.cpp
|
||||
src/controller/GenericController.h
|
||||
src/controller/Controller.cpp
|
||||
src/controller/ControllerRecordable.cpp
|
||||
|
||||
src/controller/checker/CheckerIF.h
|
||||
src/controller/checker/CheckerDDR3.cpp
|
||||
src/controller/checker/CheckerDDR4.cpp
|
||||
src/controller/checker/CheckerLPDDR4.cpp
|
||||
src/controller/checker/CheckerWideIO.cpp
|
||||
src/controller/checker/CheckerWideIO2.cpp
|
||||
src/controller/checker/CheckerGDDR5.cpp
|
||||
src/controller/checker/CheckerGDDR5X.cpp
|
||||
src/controller/checker/CheckerGDDR6.cpp
|
||||
src/controller/checker/CheckerHBM2.cpp
|
||||
|
||||
src/controller/cmdmux/CmdMuxIF.h
|
||||
src/controller/cmdmux/CmdMuxOldest.cpp
|
||||
src/controller/cmdmux/CmdMuxStrict.cpp
|
||||
|
||||
src/controller/powerdown/PowerDownManagerIF.h
|
||||
src/controller/powerdown/PowerDownManagerDummy.cpp
|
||||
src/controller/powerdown/PowerDownManagerStaggered.cpp
|
||||
|
||||
src/controller/refresh/RefreshManagerIF.h
|
||||
src/controller/refresh/RefreshManagerDummy.cpp
|
||||
src/controller/refresh/RefreshManager.cpp
|
||||
src/controller/refresh/RefreshManagerBankwise.cpp
|
||||
|
||||
src/controller/respqueue/RespQueueIF.h
|
||||
src/controller/respqueue/RespQueueFifo.cpp
|
||||
src/controller/respqueue/RespQueueReorder.cpp
|
||||
|
||||
src/controller/scheduler/SchedulerIF.h
|
||||
src/controller/scheduler/SchedulerFifo.cpp
|
||||
src/controller/scheduler/SchedulerFrFcfs.cpp
|
||||
|
||||
src/error/eccbaseclass.cpp
|
||||
src/error/ecchamming.cpp
|
||||
src/error/errormodel.cpp
|
||||
|
||||
src/error/ECC/Bit.cpp
|
||||
src/error/ECC/ECC.cpp
|
||||
src/error/ECC/Word.cpp
|
||||
|
||||
src/simulation/Arbiter.cpp
|
||||
src/simulation/DRAMSys.cpp
|
||||
src/simulation/MemoryManager.cpp
|
||||
src/simulation/Setup.cpp
|
||||
src/simulation/TemperatureController.cpp
|
||||
src/simulation/TracePlayer.cpp
|
||||
src/simulation/TraceSetup.cpp
|
||||
|
||||
src/simulation/dram/Dram.cpp
|
||||
src/simulation/dram/DramRecordable.cpp
|
||||
src/simulation/dram/DramDDR3.cpp
|
||||
src/simulation/dram/DramDDR4.cpp
|
||||
src/simulation/dram/DramLPDDR4.cpp
|
||||
src/simulation/dram/DramWideIO.cpp
|
||||
src/simulation/dram/DramWideIO2.cpp
|
||||
src/simulation/dram/DramGDDR5.cpp
|
||||
src/simulation/dram/DramGDDR5X.cpp
|
||||
src/simulation/dram/DramGDDR6.cpp
|
||||
src/simulation/dram/DramHBM2.cpp
|
||||
)
|
||||
|
||||
# Build:
|
||||
|
||||
@@ -118,21 +118,20 @@ BankMachineOpen::BankMachineOpen(SchedulerIF *scheduler, CheckerIF *checker, Ban
|
||||
sc_time BankMachineOpen::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (sleeping)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
@@ -141,12 +140,12 @@ sc_time BankMachineOpen::start()
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
nextCommand = Command::RD;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
@@ -154,13 +153,11 @@ sc_time BankMachineOpen::start()
|
||||
}
|
||||
else if (!blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
nextCommand = Command::PRE;
|
||||
}
|
||||
}
|
||||
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineClosed::BankMachineClosed(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
|
||||
@@ -169,40 +166,38 @@ BankMachineClosed::BankMachineClosed(SchedulerIF *scheduler, CheckerIF *checker,
|
||||
sc_time BankMachineClosed::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (sleeping)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
nextCommand = Command::RDA;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
}
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineOpenAdaptive::BankMachineOpenAdaptive(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
|
||||
@@ -211,21 +206,20 @@ BankMachineOpenAdaptive::BankMachineOpenAdaptive(SchedulerIF *scheduler, Checker
|
||||
sc_time BankMachineOpenAdaptive::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (sleeping)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
@@ -236,12 +230,12 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
nextCommand = Command::RDA;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
@@ -251,12 +245,12 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
nextCommand = Command::RD;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
@@ -265,12 +259,11 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
}
|
||||
else if (!blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
nextCommand = Command::PRE;
|
||||
}
|
||||
}
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineClosedAdaptive::BankMachineClosedAdaptive(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
|
||||
@@ -279,21 +272,20 @@ BankMachineClosedAdaptive::BankMachineClosedAdaptive(SchedulerIF *scheduler, Che
|
||||
sc_time BankMachineClosedAdaptive::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (sleeping)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
@@ -304,12 +296,12 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
nextCommand = Command::RD;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
@@ -319,12 +311,12 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
nextCommand = Command::RDA;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
@@ -333,11 +325,10 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
}
|
||||
else if (!blocked) // row miss TODO: remove this, can never happen
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
nextCommand = Command::PRE;
|
||||
SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy");
|
||||
}
|
||||
}
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
@@ -55,12 +55,14 @@
|
||||
#include "refresh/RefreshManagerBankwise.h"
|
||||
#include "powerdown/PowerDownManagerStaggered.h"
|
||||
#include "powerdown/PowerDownManagerDummy.h"
|
||||
#include "respqueue/RespQueueFifo.h"
|
||||
#include "respqueue/RespQueueReorder.h"
|
||||
|
||||
Controller::Controller(sc_module_name name) :
|
||||
GenericController(name)
|
||||
{
|
||||
SC_METHOD(controllerMethod);
|
||||
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEventQueue;
|
||||
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
|
||||
dont_initialize();
|
||||
|
||||
Configuration &config = Configuration::getInstance();
|
||||
@@ -187,6 +189,8 @@ Controller::Controller(sc_module_name name) :
|
||||
}
|
||||
}
|
||||
|
||||
respQueue = new RespQueueFifo();
|
||||
|
||||
startBandwidthIdleCollector();
|
||||
}
|
||||
|
||||
@@ -194,6 +198,7 @@ Controller::~Controller()
|
||||
{
|
||||
endBandwithIdleCollector();
|
||||
|
||||
delete respQueue;
|
||||
for (auto it : refreshManagers)
|
||||
delete it;
|
||||
for (auto it : powerDownManagers)
|
||||
@@ -212,14 +217,17 @@ void Controller::controllerMethod()
|
||||
releasePayload();
|
||||
|
||||
// (2) Send next result to arbiter
|
||||
if (payloadToRelease == nullptr && !responseQueue.empty())
|
||||
{
|
||||
std::pair<sc_time, tlm_generic_payload *> element = responseQueue.front();
|
||||
if (sc_time_stamp() >= element.first)
|
||||
{
|
||||
payloadToRelease = element.second;
|
||||
responseQueue.pop();
|
||||
if (payloadToRelease == nullptr)
|
||||
{
|
||||
payloadToRelease = respQueue->nextPayload();
|
||||
|
||||
if (payloadToRelease != nullptr)
|
||||
sendToFrontend(payloadToRelease, BEGIN_RESP);
|
||||
else
|
||||
{
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,22 +311,22 @@ void Controller::controllerMethod()
|
||||
|
||||
// (6) Restart bank machines and refresh managers to issue new requests for the future
|
||||
// TODO: check if all calls are necessary
|
||||
sc_time delayForNextTrigger = sc_max_time();
|
||||
sc_time timeForNextTrigger = sc_max_time();
|
||||
for (auto it : bankMachines)
|
||||
{
|
||||
sc_time localDelay = it->start();
|
||||
if (!(localDelay == SC_ZERO_TIME && readyCmdBlocked))
|
||||
delayForNextTrigger = std::min(delayForNextTrigger, localDelay);
|
||||
sc_time localTime = it->start();
|
||||
if (!(localTime == sc_time_stamp() && readyCmdBlocked))
|
||||
timeForNextTrigger = std::min(timeForNextTrigger, localTime);
|
||||
}
|
||||
if (payloadToAcquire != nullptr && sc_time_stamp() >= timeToAcquire && scheduler->hasBufferSpace(payloadToAcquire))
|
||||
acquirePayload();
|
||||
for (auto it : refreshManagers)
|
||||
delayForNextTrigger = std::min(delayForNextTrigger, it->start());
|
||||
timeForNextTrigger = std::min(timeForNextTrigger, it->start());
|
||||
for (auto it : powerDownManagers)
|
||||
delayForNextTrigger = std::min(delayForNextTrigger, it->start());
|
||||
timeForNextTrigger = std::min(timeForNextTrigger, it->start());
|
||||
|
||||
if (!(delayForNextTrigger == (sc_max_time() - sc_time_stamp())))
|
||||
controllerEvent.notify(delayForNextTrigger);
|
||||
if (timeForNextTrigger != sc_max_time())
|
||||
controllerEvent.notify(timeForNextTrigger - sc_time_stamp());
|
||||
}
|
||||
|
||||
tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans,
|
||||
@@ -357,8 +365,11 @@ tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &trans,
|
||||
if (phase == END_RD || phase == END_RDA || phase == END_WR || phase == END_WRA)
|
||||
{
|
||||
// TODO: check this part (order of responses)
|
||||
responseQueue.push({(sc_time_stamp() + delay), &trans});
|
||||
dataResponseEventQueue.notify(delay);
|
||||
respQueue->insertPayload(&trans, delay);
|
||||
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
|
||||
Rank rank = DramExtension::getRank(trans);
|
||||
ranksNumberOfPayloads[rank.ID()]--;
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "checker/CheckerIF.h"
|
||||
#include "refresh/RefreshManagerIF.h"
|
||||
#include "powerdown/PowerDownManagerIF.h"
|
||||
#include "respqueue/RespQueueIF.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
@@ -81,6 +82,7 @@ private:
|
||||
tlm_generic_payload *payloadToRelease = nullptr;
|
||||
sc_time timeToRelease = sc_max_time();
|
||||
std::queue<std::pair<sc_time, tlm_generic_payload *>> responseQueue;
|
||||
RespQueueIF *respQueue;
|
||||
|
||||
std::vector<BankMachine *> bankMachines;
|
||||
std::vector<std::vector<BankMachine *>> bankMachinesOnRank;
|
||||
@@ -94,8 +96,7 @@ private:
|
||||
void acquirePayload();
|
||||
|
||||
void controllerMethod();
|
||||
sc_event beginReqEvent, endRespEvent, controllerEvent;
|
||||
sc_event_queue dataResponseEventQueue;
|
||||
sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent;
|
||||
|
||||
// Bandwidth related
|
||||
sc_time idleStart;
|
||||
|
||||
@@ -52,7 +52,7 @@ CheckerDDR3::CheckerDDR3()
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -364,7 +364,7 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerDDR3 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR3();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -54,7 +54,7 @@ CheckerDDR4::CheckerDDR4()
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -247,7 +247,7 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR4();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -55,7 +55,7 @@ CheckerGDDR5::CheckerGDDR5()
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -108,8 +108,6 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
@@ -159,8 +157,6 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -190,8 +186,6 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
@@ -210,8 +204,6 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -239,8 +231,6 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -268,8 +258,6 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
@@ -316,15 +304,15 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerGDDR5", "Unknown command!");
|
||||
}
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerGDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -55,7 +55,7 @@ CheckerGDDR5X::CheckerGDDR5X()
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -108,8 +108,6 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
@@ -159,8 +157,6 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -190,8 +186,6 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
@@ -210,8 +204,6 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -239,8 +231,6 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -268,8 +258,6 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
@@ -316,15 +304,15 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerGDDR5X", "Unknown command!");
|
||||
}
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerGDDR5X final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5X();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -54,7 +54,7 @@ CheckerGDDR6::CheckerGDDR6()
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -104,8 +104,6 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
@@ -155,8 +153,6 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -186,8 +182,6 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
@@ -206,8 +200,6 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -235,8 +227,6 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -264,8 +254,6 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
@@ -309,15 +297,15 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerGDDR6", "Unknown command!");
|
||||
}
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerGDDR6 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR6();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -55,7 +55,7 @@ CheckerHBM2::CheckerHBM2()
|
||||
burstClocks = (memSpec->BurstLength / 2) * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -312,7 +312,7 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
reportFatal("CheckerHBM2", "Unknown command!");
|
||||
}
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerHBM2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerHBM2();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -46,7 +46,7 @@ class CheckerIF
|
||||
public:
|
||||
virtual ~CheckerIF() {}
|
||||
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const = 0;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const = 0;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ CheckerLPDDR4::CheckerLPDDR4()
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -269,7 +269,7 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerLPDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerLPDDR4();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -52,7 +52,7 @@ CheckerWideIO::CheckerWideIO()
|
||||
burstClocks = memSpec->BurstLength * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -216,7 +216,7 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->clk);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerWideIO final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerWideIO();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -50,7 +50,7 @@ CheckerWideIO2::CheckerWideIO2()
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -262,7 +262,7 @@ sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, Ba
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerWideIO2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerWideIO2();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -41,5 +41,5 @@ std::pair<Command, tlm_generic_payload *> PowerDownManagerDummy::getNextCommand(
|
||||
|
||||
sc_time PowerDownManagerDummy::start()
|
||||
{
|
||||
return sc_max_time() - sc_time_stamp();
|
||||
return sc_max_time();
|
||||
}
|
||||
|
||||
@@ -88,7 +88,6 @@ std::pair<Command, tlm_generic_payload *> PowerDownManagerStaggered::getNextComm
|
||||
sc_time PowerDownManagerStaggered::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (triggered)
|
||||
{
|
||||
@@ -110,11 +109,10 @@ sc_time PowerDownManagerStaggered::start()
|
||||
else // if (state == PdmState::Refresh)
|
||||
nextCommand = Command::REFA;
|
||||
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
}
|
||||
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
void PowerDownManagerStaggered::updateState(Command command)
|
||||
|
||||
@@ -78,7 +78,7 @@ sc_time RefreshManager::start()
|
||||
{
|
||||
powerDownManager->triggerExit(TriggerSource::RefreshManager);
|
||||
if (sleeping)
|
||||
return sc_max_time() - sc_time_stamp();
|
||||
return timeToSchedule;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalAB())
|
||||
{
|
||||
@@ -86,7 +86,6 @@ sc_time RefreshManager::start()
|
||||
state = RmState::Regular;
|
||||
}
|
||||
|
||||
sc_time delay;
|
||||
if (state == RmState::Regular)
|
||||
{
|
||||
bool forcedRefresh = (flexibilityCounter == maxPostponed);
|
||||
@@ -94,7 +93,7 @@ sc_time RefreshManager::start()
|
||||
{
|
||||
flexibilityCounter++;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -108,9 +107,8 @@ sc_time RefreshManager::start()
|
||||
nextCommand = Command::PREA;
|
||||
else
|
||||
nextCommand = Command::REFA;
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
else // if (state == RmState::Pulledin)
|
||||
@@ -119,19 +117,18 @@ sc_time RefreshManager::start()
|
||||
{
|
||||
state = RmState::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nextCommand stays Command::REFA
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
|
||||
void RefreshManager::updateState(Command command, tlm_generic_payload *)
|
||||
|
||||
@@ -76,7 +76,7 @@ sc_time RefreshManagerBankwise::start()
|
||||
{
|
||||
powerDownManager->triggerExit(TriggerSource::RefreshManager);
|
||||
if (sleeping)
|
||||
return sc_max_time() - sc_time_stamp();
|
||||
return timeToSchedule;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalPB())
|
||||
{
|
||||
@@ -84,7 +84,6 @@ sc_time RefreshManagerBankwise::start()
|
||||
state = RmState::Regular;
|
||||
}
|
||||
|
||||
sc_time delay;
|
||||
if (state == RmState::Regular)
|
||||
{
|
||||
currentIterator = remainingBankMachines.begin();
|
||||
@@ -107,7 +106,7 @@ sc_time RefreshManagerBankwise::start()
|
||||
{
|
||||
flexibilityCounter++;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -115,10 +114,9 @@ sc_time RefreshManagerBankwise::start()
|
||||
nextCommand = Command::PRE;
|
||||
else
|
||||
nextCommand = Command::REFB;
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank,
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
currentBankMachine->getBankGroup(), currentBankMachine->getBank());
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
else // if (state == RmState::Pulledin)
|
||||
@@ -140,7 +138,7 @@ sc_time RefreshManagerBankwise::start()
|
||||
{
|
||||
state = RmState::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -148,15 +146,14 @@ sc_time RefreshManagerBankwise::start()
|
||||
nextCommand = Command::PRE;
|
||||
else
|
||||
nextCommand = Command::REFB;
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank,
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
currentBankMachine->getBankGroup(), currentBankMachine->getBank());
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::updateState(Command command, tlm_generic_payload *payload)
|
||||
|
||||
@@ -41,5 +41,5 @@ std::pair<Command, tlm_generic_payload *> RefreshManagerDummy::getNextCommand()
|
||||
|
||||
sc_time RefreshManagerDummy::start()
|
||||
{
|
||||
return sc_max_time() - sc_time_stamp();
|
||||
return sc_max_time();
|
||||
}
|
||||
|
||||
65
DRAMSys/library/src/controller/respqueue/RespQueueFifo.cpp
Normal file
65
DRAMSys/library/src/controller/respqueue/RespQueueFifo.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 "RespQueueFifo.h"
|
||||
|
||||
void RespQueueFifo::insertPayload(tlm_generic_payload *payload, sc_time delay)
|
||||
{
|
||||
buffer.push({payload, sc_time_stamp() + delay});
|
||||
}
|
||||
|
||||
tlm_generic_payload *RespQueueFifo::nextPayload()
|
||||
{
|
||||
if (!buffer.empty())
|
||||
{
|
||||
std::pair<tlm_generic_payload *, sc_time> element = buffer.front();
|
||||
if (element.second <= sc_time_stamp())
|
||||
{
|
||||
buffer.pop();
|
||||
return element.first;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sc_time RespQueueFifo::getTriggerTime() const
|
||||
{
|
||||
if (!buffer.empty())
|
||||
{
|
||||
sc_time triggerTime = buffer.front().second;
|
||||
if (triggerTime > sc_time_stamp())
|
||||
return triggerTime;
|
||||
}
|
||||
return sc_max_time();
|
||||
}
|
||||
57
DRAMSys/library/src/controller/respqueue/RespQueueFifo.h
Normal file
57
DRAMSys/library/src/controller/respqueue/RespQueueFifo.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 RESPQUEUEFIFO_H
|
||||
#define RESPQUEUEFIFO_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "RespQueueIF.h"
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class RespQueueFifo final : public RespQueueIF
|
||||
{
|
||||
public:
|
||||
virtual void insertPayload(tlm_generic_payload *, sc_time) override;
|
||||
virtual tlm_generic_payload *nextPayload() override;
|
||||
virtual sc_time getTriggerTime() const override;
|
||||
|
||||
private:
|
||||
std::queue<std::pair<tlm_generic_payload *, sc_time>> buffer;
|
||||
};
|
||||
|
||||
#endif // RESPQUEUEFIFO_H
|
||||
51
DRAMSys/library/src/controller/respqueue/RespQueueIF.h
Normal file
51
DRAMSys/library/src/controller/respqueue/RespQueueIF.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 RESPQUEUEIF_H
|
||||
#define RESPQUEUEIF_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class RespQueueIF
|
||||
{
|
||||
public:
|
||||
virtual void insertPayload(tlm_generic_payload *, sc_time) = 0;
|
||||
virtual tlm_generic_payload *nextPayload() = 0;
|
||||
virtual sc_time getTriggerTime() const = 0;
|
||||
};
|
||||
|
||||
#endif // RESPQUEUEIF_H
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 "RespQueueReorder.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
void RespQueueReorder::insertPayload(tlm_generic_payload *payload, sc_time delay)
|
||||
{
|
||||
buffer[DramExtension::getPayloadID(payload)] = {payload, sc_time_stamp() + delay};
|
||||
}
|
||||
|
||||
tlm_generic_payload *RespQueueReorder::nextPayload()
|
||||
{
|
||||
if (!buffer.empty())
|
||||
{
|
||||
if (buffer.begin()->first == currentPayloadID)
|
||||
{
|
||||
std::pair<tlm_generic_payload *, sc_time> element = buffer.begin()->second;
|
||||
if (element.second <= sc_time_stamp())
|
||||
{
|
||||
buffer.erase(currentPayloadID++);
|
||||
return element.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sc_time RespQueueReorder::getTriggerTime() const
|
||||
{
|
||||
if (!buffer.empty())
|
||||
{
|
||||
if (buffer.begin()->first == currentPayloadID)
|
||||
{
|
||||
sc_time triggerTime = buffer.begin()->second.second;
|
||||
if (triggerTime > sc_time_stamp())
|
||||
return triggerTime;
|
||||
}
|
||||
}
|
||||
return sc_max_time();
|
||||
}
|
||||
58
DRAMSys/library/src/controller/respqueue/RespQueueReorder.h
Normal file
58
DRAMSys/library/src/controller/respqueue/RespQueueReorder.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 RESPQUEUEREORDER_H
|
||||
#define RESPQUEUEREORDER_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "RespQueueIF.h"
|
||||
#include <map>
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class RespQueueReorder final : public RespQueueIF
|
||||
{
|
||||
public:
|
||||
virtual void insertPayload(tlm_generic_payload *, sc_time) override;
|
||||
virtual tlm_generic_payload *nextPayload() override;
|
||||
virtual sc_time getTriggerTime() const override;
|
||||
|
||||
private:
|
||||
uint64_t currentPayloadID = 0;
|
||||
// Muss die Zeit aller Payloads gespeichert werden?
|
||||
std::map<uint64_t, std::pair<tlm_generic_payload *, sc_time>> buffer;
|
||||
};
|
||||
|
||||
#endif // RESPQUEUEREORDER_H
|
||||
Reference in New Issue
Block a user