Bugfix: Commands on one bank can overlap now.

This commit is contained in:
Lukas Steiner (2)
2019-07-30 13:30:59 +02:00
parent fb9abb9cee
commit b477424a98
5 changed files with 28 additions and 62 deletions

View File

@@ -3,26 +3,6 @@
BankMachine::BankMachine(SchedulerIF *scheduler, CheckerDDR3New *checker, Bank bank)
: scheduler(scheduler), checker(checker), bank(bank) {}
tlm_generic_payload *BankMachine::getNextStateAndResult()
{
tlm_generic_payload *payloadToReturn = nullptr;
if (currentState == BmState::Activating)
currentState = BmState::Activated;
else if (currentState == BmState::Precharging)
currentState = BmState::Precharged;
else if (currentState == BmState::Reading || currentState == BmState::Writing)
{
currentState = BmState::Activated;
payloadToReturn = currentPayload;
currentPayload = nullptr;
}
else
SC_REPORT_FATAL(("BankMachine " + bank.toString()).c_str(), "Wrong command!");
return payloadToReturn;
}
sc_time BankMachine::startBankMachine()
{
if (currentPayload == nullptr)
@@ -80,13 +60,11 @@ std::pair<Command, tlm_generic_payload *> BankMachine::getNextCommand()
void BankMachine::updateState(Command command)
{
if (command == Command::ACT)
currentState = BmState::Activating;
currentState = BmState::Activated;
else if (command == Command::PRE)
currentState = BmState::Precharging;
else if (command == Command::RD)
currentState = BmState::Reading;
else if (command == Command::WR)
currentState = BmState::Writing;
currentState = BmState::Precharged;
else if (command == Command::RD || command == Command::WR)
currentPayload = nullptr;
else
SC_REPORT_FATAL("BankMachine", "Unknown phase");
}

View File

@@ -18,18 +18,13 @@ class CheckerDDR3New;
enum class BmState
{
Precharged,
Activated,
Precharging,
Activating,
Reading,
Writing
Activated
};
class BankMachine
{
public:
BankMachine(SchedulerIF *, CheckerDDR3New*, Bank);
tlm_generic_payload *getNextStateAndResult();
sc_time startBankMachine();
std::pair<Command, tlm_generic_payload *> getNextCommand();
void updateState(Command);

View File

@@ -21,13 +21,10 @@ ControllerNew::ControllerNew(sc_module_name name) :
state = new ControllerState("Controller", &Configuration::getInstance());
checker = new CheckerDDR3New(Configuration::getInstance(), *state);
scheduler = new SchedulerFrFcfs();
scheduler = new SchedulerFifo();
for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++)
{
bankMachines[Bank(bankID)] = new BankMachine(scheduler, checker, Bank(bankID));
commandFinishedTime[Bank(bankID)] = SC_ZERO_TIME;
}
commandMux = new CmdMuxOldest();
commandMux = new CmdMuxStrict();
}
ControllerNew::~ControllerNew()
@@ -71,9 +68,12 @@ tlm_sync_enum ControllerNew::nb_transport_bw(tlm_generic_payload &trans,
{
printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " +
delay.to_string());
Bank bank = DramExtension::getExtension(trans).getBank();
commandFinishedTime[bank] = sc_time_stamp() + delay;
triggerEventQueueAfterDelay(delay);
if (phase == END_RD || phase == END_WR)
{
std::pair<sc_time, tlm_generic_payload *> element((sc_time_stamp() + delay), &trans);
responseQueue.push(element);
}
return TLM_ACCEPTED;
}
@@ -120,29 +120,23 @@ void ControllerNew::controllerMethod()
printDebugMessage("Total number of payloads exceeded, backpressure!");
}
// (3) Update states of bank machines and get results if ready
for (auto it : bankMachines)
// (3) Send result to arbiter
if (payloadToRelease == nullptr && !responseQueue.empty())
{
if (commandFinishedTime[it.first] == sc_time_stamp())
std::pair<sc_time, tlm_generic_payload *> element = responseQueue.front();
if (sc_time_stamp() >= element.first)
{
tlm_generic_payload *result = it.second->getNextStateAndResult();
if (result != nullptr)
responseQueue.push(result);
payloadToRelease = element.second;
responseQueue.pop();
sendToFrontend(payloadToRelease, BEGIN_RESP);
}
}
// (4) Send result to arbiter
if (payloadToRelease == nullptr && !responseQueue.empty())
{
payloadToRelease = responseQueue.front();
sendToFrontend(payloadToRelease, BEGIN_RESP);
}
// (5) Start bank machines to issue new requests for current time
// (4) Start bank machines to issue new requests for current time
for (auto it : bankMachines)
it.second->startBankMachine();
// (6) Choose one request and send it to DRAM
// (5) Choose one request and send it to DRAM
std::vector<std::pair<Command, tlm_generic_payload *>> readyCommands;
std::pair<Command, tlm_generic_payload *> result;
for (auto it : bankMachines)
@@ -155,10 +149,14 @@ void ControllerNew::controllerMethod()
{
result = commandMux->selectCommand(readyCommands);
if (result.second != nullptr)
{
Bank bank = DramExtension::getBank(result.second);
bankMachines[bank]->updateState(result.first);
sendToDram(result.first, result.second);
}
}
// (7) Restart bank machines to issue new requests for the future
// (6) Restart bank machines to issue new requests for the future
for (auto it : bankMachines)
{
sc_time delay = it.second->startBankMachine();
@@ -172,7 +170,6 @@ void ControllerNew::releasePayload()
uint64_t id = DramExtension::getPayloadID(payloadToRelease);
printDebugMessage("Payload " + std::to_string(id) + " left system.");
responseQueue.pop();
payloadToRelease->release();
numberOfPayloads--;
payloadToRelease = nullptr;
@@ -186,10 +183,8 @@ void ControllerNew::acquirePayload()
scheduler->storeRequest(payloadToAcquire);
payloadToAcquire->acquire();
numberOfPayloads++;
payloadToAcquire->set_response_status(TLM_OK_RESPONSE);
sendToFrontend(payloadToAcquire, END_REQ);
payloadToAcquire = nullptr;
}
@@ -205,8 +200,6 @@ void ControllerNew::sendToDram(Command command, tlm_generic_payload *payload)
ScheduledCommand scheduledCommand(command, sc_time_stamp(), execTime, *payload);
state->cleanUp(sc_time_stamp());
state->change(scheduledCommand);
Bank bank = scheduledCommand.getBank();
bankMachines[bank]->updateState(command);
sc_time delay = SC_ZERO_TIME;
tlm_phase phase;

View File

@@ -4,6 +4,7 @@
#include <map>
#include <queue>
#include <vector>
#include <utility>
#include <systemc.h>
#include <tlm.h>
#include <tlm_utils/simple_initiator_socket.h>
@@ -49,7 +50,7 @@ protected:
sc_time timeToAcquire = SC_ZERO_TIME;
tlm_generic_payload *payloadToRelease = nullptr;
sc_time timeToRelease = SC_ZERO_TIME;
std::queue<tlm_generic_payload *> responseQueue;
std::queue<std::pair<sc_time, tlm_generic_payload *>> responseQueue;
DebugManager *debugManager;

View File

@@ -29,7 +29,6 @@ void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payl
state->cleanUp(sc_time_stamp());
state->change(scheduledCommand);
Bank bank = scheduledCommand.getBank();
bankMachines[bank]->updateState(command);
sc_time delay = SC_ZERO_TIME;
tlm_phase phase;