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:
@@ -27,13 +27,12 @@
|
||||
#include "../../common/DebugManager.h"
|
||||
|
||||
|
||||
namespace core {
|
||||
|
||||
std::string ControllerCore::senderName = "Controller Core";
|
||||
|
||||
ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map<Bank, int>& numberOfPayloads) :
|
||||
config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), numberOfPayloads(
|
||||
numberOfPayloads), commandChecker(), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(*this)
|
||||
ControllerCore::ControllerCore(IController& wrapperConnector, std::map<Bank, int>& numberOfPayloads) :
|
||||
config(Configuration::getInstance()), state(&config), controller(wrapperConnector), numberOfPayloads(
|
||||
numberOfPayloads), commandChecker()
|
||||
|
||||
{
|
||||
commandChecker[Command::Activate] = new ActivateChecker(config, state);
|
||||
@@ -92,16 +91,6 @@ ControllerCore::~ControllerCore()
|
||||
delete powerDownManager;
|
||||
}
|
||||
|
||||
void ControllerCore::saveState()
|
||||
{
|
||||
savedState = state;
|
||||
}
|
||||
|
||||
void ControllerCore::resetState()
|
||||
{
|
||||
state = savedState;
|
||||
}
|
||||
|
||||
void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload)
|
||||
{
|
||||
sc_time time = sc_time_stamp();
|
||||
@@ -117,28 +106,28 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload)
|
||||
}
|
||||
}
|
||||
|
||||
bool ControllerCore::scheduleRequest(tlm::tlm_generic_payload& payload)
|
||||
void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload &payload)
|
||||
{
|
||||
sc_time start = clkAlign(sc_time_stamp());
|
||||
state.cleanUp(start);
|
||||
|
||||
saveState();
|
||||
|
||||
CommandSequence sequence = commandSequenceGenerator.generateCommandSequence(payload);
|
||||
CommandSchedule schedule = commandSequenceScheduler.schedule(sequence, start, payload);
|
||||
|
||||
if (refreshManager->hasCollision(schedule))
|
||||
{
|
||||
resetState();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
send(schedule, payload);
|
||||
return true;
|
||||
}
|
||||
ScheduledCommand scheduledCommand = schedule(command, start, payload);
|
||||
state.change(scheduledCommand);
|
||||
controller.send(scheduledCommand, payload);
|
||||
}
|
||||
|
||||
ScheduledCommand ControllerCore::schedule(Command command, sc_time start,
|
||||
tlm::tlm_generic_payload& payload)
|
||||
{
|
||||
ControllerCore::printDebugMessage("Scheduling command " + commandToString(command) + " on " + DramExtension::getBank(payload).toString());
|
||||
ICommandChecker& checker = getCommandChecker(command);
|
||||
sc_time executionTime = getExecutionTime(command, payload);
|
||||
ScheduledCommand scheduledCommand(command, start, executionTime, DramExtension::getExtension(payload));
|
||||
checker.delayToSatisfyConstraints(scheduledCommand);
|
||||
return scheduledCommand;
|
||||
}
|
||||
|
||||
|
||||
bool ControllerCore::bankIsBusy(Bank bank)
|
||||
{
|
||||
sc_time time = sc_time_stamp();
|
||||
@@ -148,9 +137,10 @@ bool ControllerCore::bankIsBusy(Bank bank)
|
||||
return false;
|
||||
else if (lastScheduledCommand.commandIsIn( { Command::Write, Command::Read }))
|
||||
{
|
||||
// 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::WriteA, Command::ReadA }))
|
||||
else if (lastScheduledCommand.commandIsIn( { Command::WriteA, Command::ReadA, Command::Precharge, Command::PrechargeAll, Command::Activate }))
|
||||
{
|
||||
return (time < lastScheduledCommand.getEnd());
|
||||
}
|
||||
@@ -165,7 +155,7 @@ bool ControllerCore::bankIsBusy(Bank bank)
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("Core", "Last command in command sequence was activate or precharge. This really doesn't make sense :D.");
|
||||
SC_REPORT_FATAL("Core", "Last command unkown");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -197,14 +187,6 @@ std::vector<Bank> ControllerCore::getFreeBanks()
|
||||
return freeBanks;
|
||||
}
|
||||
|
||||
void ControllerCore::send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const
|
||||
{
|
||||
for (const ScheduledCommand& cmd : schedule.getScheduledCommands())
|
||||
{
|
||||
wrapper.send(cmd, payload);
|
||||
}
|
||||
}
|
||||
|
||||
ICommandChecker& ControllerCore::getCommandChecker(Command command)
|
||||
{
|
||||
return *getElementFromMap(commandChecker, command);
|
||||
@@ -215,5 +197,4 @@ void ControllerCore::printDebugMessage(string message)
|
||||
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, message);
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user