Relocated the python scripts. They now live in the analyzer directory and are deployed to the output folder when building the analyzer.
Major change to simulation logic in dramSys: Commands in a transaction are now scheduled one at a time, instead of scheduling a whole transaction at once. Since single commands (e.g. Pre or Act) are not that long, refreshes are allowed to be delayed to allow a command to finsh. Consequently, the whole loop in the ControllerCore about trying to scheduleding a transaction and aborting it when it collides with a refresh could be ommitted. Lastly, Fifo_Strict has been added, which is a Fifo Scheduler that forces the read and write transactions, even between different banks to be executed in order. Fifo and FR_FCFS have been modified to fit into the new scheduling logic.
This commit is contained in:
@@ -12,12 +12,14 @@
|
||||
#include "../TimingCalculation.h"
|
||||
|
||||
using namespace tlm;
|
||||
namespace core {
|
||||
|
||||
RefreshManager::RefreshManager(ControllerCore& controller) :
|
||||
controller(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME)
|
||||
controllerCore(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME)
|
||||
{
|
||||
setupTransactions();
|
||||
for (Bank bank : controller.getBanks())
|
||||
{
|
||||
setUpDummy(refreshPayloads[bank], bank);
|
||||
}
|
||||
planNextRefresh();
|
||||
}
|
||||
|
||||
@@ -25,58 +27,48 @@ RefreshManager::~RefreshManager()
|
||||
{
|
||||
}
|
||||
|
||||
bool RefreshManager::hasCollision(const CommandSchedule& schedule)
|
||||
{
|
||||
return schedule.getStart() < controller.state.getLastCommand(Command::AutoRefresh).getEnd() || schedule.getEnd() > nextPlannedRefresh;
|
||||
}
|
||||
|
||||
bool RefreshManager::hasCollision(const ScheduledCommand& command)
|
||||
{
|
||||
|
||||
return command.getStart() < controller.state.getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh;
|
||||
return command.getStart() < controllerCore.state.getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh;
|
||||
}
|
||||
|
||||
void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
|
||||
{
|
||||
sc_assert(!isInvalidated(payload, time));
|
||||
|
||||
if (!controller.state.rowBufferStates.allRowBuffersAreClosed())
|
||||
if (!controllerCore.state.rowBufferStates.allRowBuffersAreClosed())
|
||||
{
|
||||
ScheduledCommand precharge(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]),
|
||||
DramExtension::getExtension(refreshPayloads[Bank(0)]));
|
||||
controller.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(precharge);
|
||||
sendToAllBanks(precharge);
|
||||
ScheduledCommand prechargeAllMaster(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]),
|
||||
refreshPayloads[Bank(0)]);
|
||||
controllerCore.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(prechargeAllMaster);
|
||||
|
||||
for (Bank bank : controllerCore.getBanks())
|
||||
{
|
||||
ScheduledCommand prechargeAll(Command::PrechargeAll, prechargeAllMaster.getStart(), prechargeAllMaster.getExecutionTime(),
|
||||
refreshPayloads[bank]);
|
||||
controllerCore.state.change(prechargeAll);
|
||||
controllerCore.controller.send(prechargeAll, refreshPayloads[bank]);
|
||||
}
|
||||
}
|
||||
|
||||
ScheduledCommand nextRefresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayloads[Bank(0)]),
|
||||
DramExtension::getExtension(refreshPayloads[Bank(0)]));
|
||||
controller.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(nextRefresh);
|
||||
sendToAllBanks(nextRefresh);
|
||||
|
||||
for (Bank bank : controller.getBanks())
|
||||
for (Bank bank : controllerCore.getBanks())
|
||||
{
|
||||
ScheduledCommand refresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayloads[bank]),
|
||||
DramExtension::getExtension(refreshPayloads[bank]));
|
||||
controllerCore.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(refresh);
|
||||
controllerCore.state.change(refresh);
|
||||
controllerCore.controller.send(refresh, refreshPayloads[bank]);
|
||||
|
||||
DramExtension::getExtension(refreshPayloads[bank]).incrementRow();
|
||||
}
|
||||
|
||||
planNextRefresh();
|
||||
}
|
||||
|
||||
void RefreshManager::sendToAllBanks(ScheduledCommand& command)
|
||||
{
|
||||
for (Bank bank : controller.getBanks())
|
||||
{
|
||||
tlm_generic_payload& payload = refreshPayloads[bank];
|
||||
DramExtension extension = DramExtension::getExtension(payload);
|
||||
ScheduledCommand cmd(command.getCommand(), command.getStart(), command.getExecutionTime(), extension);
|
||||
controller.state.change(cmd);
|
||||
controller.wrapper.send(cmd, payload);
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshManager::planNextRefresh()
|
||||
{
|
||||
nextPlannedRefresh += timing.tREFI;
|
||||
controller.wrapper.send(REFTrigger, nextPlannedRefresh, refreshPayloads[Bank(0)]);
|
||||
controllerCore.controller.send(REFTrigger, nextPlannedRefresh, refreshPayloads[Bank(0)]);
|
||||
}
|
||||
|
||||
void RefreshManager::reInitialize(Bank /*bank*/, sc_time time)
|
||||
@@ -85,17 +77,8 @@ void RefreshManager::reInitialize(Bank /*bank*/, sc_time time)
|
||||
planNextRefresh();
|
||||
}
|
||||
|
||||
bool core::RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time)
|
||||
bool RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time)
|
||||
{
|
||||
return nextPlannedRefresh > time;
|
||||
}
|
||||
|
||||
void RefreshManager::setupTransactions()
|
||||
{
|
||||
for (Bank bank : controller.getBanks())
|
||||
{
|
||||
setUpDummy(refreshPayloads[bank], bank);
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace core */
|
||||
|
||||
Reference in New Issue
Block a user