First working implementation.
This commit is contained in:
@@ -119,22 +119,41 @@ void TlmRecorder::recordPhase(tlm_generic_payload& trans, const tlm_phase& phase
|
||||
{
|
||||
const sc_time& currentTime = sc_time_stamp();
|
||||
|
||||
if (currentTransactionsInSystem.find(&trans) == currentTransactionsInSystem.end())
|
||||
introduceTransactionSystem(trans);
|
||||
|
||||
if (phase == BEGIN_REQ || phase == BEGIN_RESP)
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
introduceTransactionToSystem(trans);
|
||||
std::string phaseName = getPhaseName(phase).substr(6);
|
||||
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(phaseName, currentTime + delay);
|
||||
}
|
||||
if (phase == BEGIN_RESP)
|
||||
{
|
||||
std::string phaseName = getPhaseName(phase).substr(6);
|
||||
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(phaseName, currentTime + delay);
|
||||
}
|
||||
else if (phase == END_REQ || phase == END_RESP)
|
||||
else if (phase == END_REQ)
|
||||
{
|
||||
assert(getPhaseName(phase).substr(4) == currentTransactionsInSystem.at(&trans).recordedPhases.back().name);
|
||||
// TODO: this assumes that the controller does not start with a transaction until END_REQ has been sent, which is not true any more for big transactions
|
||||
// BEGIN_REQ is always the first phase of a normal transaction
|
||||
currentTransactionsInSystem.at(&trans).recordedPhases.front().interval.end = currentTime + delay;
|
||||
}
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
// BEGIN_RESP is always the last phase of a normal transaction at this point
|
||||
currentTransactionsInSystem.at(&trans).recordedPhases.back().interval.end = currentTime + delay;
|
||||
}
|
||||
else if (isFixedCommandPhase(phase))
|
||||
{
|
||||
tlm_generic_payload* keyTrans;
|
||||
if (ChildExtension::isChildTrans(trans))
|
||||
{
|
||||
keyTrans = &trans.get_extension<ChildExtension>()->getParentTrans();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentTransactionsInSystem.find(&trans) == currentTransactionsInSystem.end())
|
||||
introduceTransactionToSystem(trans);
|
||||
keyTrans = &trans;
|
||||
}
|
||||
|
||||
std::string phaseName = getPhaseName(phase).substr(6); // remove "BEGIN_"
|
||||
const ControllerExtension& extension = ControllerExtension::getExtension(trans);
|
||||
TimeInterval intervalOnDataStrobe;
|
||||
@@ -145,7 +164,7 @@ void TlmRecorder::recordPhase(tlm_generic_payload& trans, const tlm_phase& phase
|
||||
intervalOnDataStrobe.end = currentTime + intervalOnDataStrobe.end;
|
||||
}
|
||||
|
||||
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(std::move(phaseName),
|
||||
currentTransactionsInSystem.at(keyTrans).recordedPhases.emplace_back(std::move(phaseName),
|
||||
std::move(TimeInterval(currentTime + delay,
|
||||
currentTime + delay + memSpec.getExecutionTime(Command(phase), trans))),
|
||||
std::move(intervalOnDataStrobe), extension.getRank(), extension.getBankGroup(), extension.getBank(),
|
||||
@@ -181,7 +200,7 @@ void TlmRecorder::recordDebugMessage(const std::string &message, const sc_time &
|
||||
|
||||
// ------------- internal -----------------------
|
||||
|
||||
void TlmRecorder::introduceTransactionSystem(tlm_generic_payload& trans)
|
||||
void TlmRecorder::introduceTransactionToSystem(tlm_generic_payload& trans)
|
||||
{
|
||||
totalNumTransactions++;
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ private:
|
||||
void openDB(const std::string &dbName);
|
||||
void closeConnection();
|
||||
|
||||
void introduceTransactionSystem(tlm::tlm_generic_payload &trans);
|
||||
void introduceTransactionToSystem(tlm::tlm_generic_payload &trans);
|
||||
void removeTransactionFromSystem(tlm::tlm_generic_payload &trans);
|
||||
|
||||
void terminateRemainingTransactions();
|
||||
|
||||
@@ -360,3 +360,103 @@ bool operator !=(const Column &lhs, const Column &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
|
||||
tlm::tlm_extension_base* ChildExtension::clone() const
|
||||
{
|
||||
return new ChildExtension(*parentTrans);
|
||||
}
|
||||
|
||||
void ChildExtension::copy_from(const tlm::tlm_extension_base& ext)
|
||||
{
|
||||
const auto& cpyFrom = dynamic_cast<const ChildExtension&>(ext);
|
||||
parentTrans = cpyFrom.parentTrans;
|
||||
}
|
||||
|
||||
tlm::tlm_generic_payload& ChildExtension::getParentTrans()
|
||||
{
|
||||
return *parentTrans;
|
||||
}
|
||||
|
||||
void ChildExtension::setExtension(tlm::tlm_generic_payload& childTrans, tlm::tlm_generic_payload& parentTrans)
|
||||
{
|
||||
auto* extension = childTrans.get_extension<ChildExtension>();
|
||||
|
||||
if (extension != nullptr)
|
||||
{
|
||||
extension->parentTrans = &parentTrans;
|
||||
}
|
||||
else
|
||||
{
|
||||
extension = new ChildExtension(parentTrans);
|
||||
childTrans.set_auto_extension(extension);
|
||||
}
|
||||
}
|
||||
|
||||
bool ChildExtension::isChildTrans(const tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
if (trans.get_extension<ChildExtension>() != nullptr)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChildExtension::notifyChildTransCompletion()
|
||||
{
|
||||
return parentTrans->get_extension<ParentExtension>()->notifyChildTransCompletion();
|
||||
}
|
||||
|
||||
tlm_extension_base* ParentExtension::clone() const
|
||||
{
|
||||
return new ParentExtension(childTranses);
|
||||
}
|
||||
|
||||
void ParentExtension::copy_from(const tlm_extension_base& ext)
|
||||
{
|
||||
const auto& cpyFrom = dynamic_cast<const ParentExtension&>(ext);
|
||||
childTranses = cpyFrom.childTranses;
|
||||
}
|
||||
|
||||
bool ParentExtension::isParentTrans(const tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
auto* extension = trans.get_extension<ParentExtension>();
|
||||
if (extension != nullptr)
|
||||
return !extension->childTranses.empty();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void ParentExtension::setExtension(tlm::tlm_generic_payload& parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses)
|
||||
{
|
||||
auto* extension = parentTrans.get_extension<ParentExtension>();
|
||||
|
||||
if (extension != nullptr)
|
||||
{
|
||||
extension->childTranses = std::move(childTranses);
|
||||
extension->nextEndReqChildId = 0;
|
||||
extension->completedChildTranses = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
extension = new ParentExtension(std::move(childTranses));
|
||||
parentTrans.set_auto_extension(extension);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<tlm::tlm_generic_payload*>& ParentExtension::getChildTranses()
|
||||
{
|
||||
return childTranses;
|
||||
}
|
||||
|
||||
bool ParentExtension::notifyChildTransCompletion()
|
||||
{
|
||||
completedChildTranses++;
|
||||
return completedChildTranses == childTranses.size();
|
||||
}
|
||||
|
||||
void ParentExtension::releaseChildTranses()
|
||||
{
|
||||
std::for_each(childTranses.begin(), childTranses.end(),
|
||||
[](tlm::tlm_generic_payload* childTrans){childTrans->release();});
|
||||
childTranses.clear();
|
||||
}
|
||||
@@ -252,4 +252,42 @@ bool operator!=(const Row &lhs, const Row &rhs);
|
||||
bool operator==(const Column &lhs, const Column &rhs);
|
||||
bool operator!=(const Column &lhs, const Column &rhs);
|
||||
|
||||
class ChildExtension : public tlm::tlm_extension<ChildExtension>
|
||||
{
|
||||
private:
|
||||
tlm::tlm_generic_payload* parentTrans;
|
||||
explicit ChildExtension(tlm::tlm_generic_payload& parentTrans) : parentTrans(&parentTrans) {}
|
||||
|
||||
public:
|
||||
//ChildExtension() = delete;
|
||||
|
||||
tlm::tlm_extension_base* clone() const override;
|
||||
void copy_from(const tlm::tlm_extension_base& ext) override;
|
||||
tlm::tlm_generic_payload& getParentTrans();
|
||||
static void setExtension(tlm::tlm_generic_payload& childTrans, tlm::tlm_generic_payload& parentTrans);
|
||||
static bool isChildTrans(const tlm::tlm_generic_payload& trans);
|
||||
bool notifyChildTransCompletion();
|
||||
};
|
||||
|
||||
class ParentExtension : public tlm::tlm_extension<ParentExtension>
|
||||
{
|
||||
private:
|
||||
std::vector<tlm::tlm_generic_payload*> childTranses;
|
||||
unsigned nextEndReqChildId = 0;
|
||||
unsigned completedChildTranses = 0;
|
||||
explicit ParentExtension(std::vector<tlm::tlm_generic_payload*> _childTranses)
|
||||
: childTranses(std::move(_childTranses)) {}
|
||||
|
||||
public:
|
||||
ParentExtension() = delete;
|
||||
|
||||
tlm_extension_base* clone() const override;
|
||||
void copy_from(const tlm_extension_base& ext) override;
|
||||
static bool isParentTrans(const tlm::tlm_generic_payload& trans);
|
||||
static void setExtension(tlm::tlm_generic_payload& parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses);
|
||||
const std::vector<tlm::tlm_generic_payload*>& getChildTranses();
|
||||
bool notifyChildTransCompletion();
|
||||
void releaseChildTranses();
|
||||
};
|
||||
|
||||
#endif // DRAMEXTENSIONS_H
|
||||
|
||||
@@ -72,7 +72,8 @@ using namespace tlm;
|
||||
Controller::Controller(const sc_module_name& name, const Configuration& config, const AddressDecoder& addressDecoder) :
|
||||
ControllerIF(name, config), addressDecoder(addressDecoder),
|
||||
thinkDelayFw(config.thinkDelayFw), thinkDelayBw(config.thinkDelayBw),
|
||||
phyDelayFw(config.phyDelayFw), phyDelayBw(config.phyDelayBw)
|
||||
phyDelayFw(config.phyDelayFw), phyDelayBw(config.phyDelayBw),
|
||||
maxBytesPerBurst(config.memSpec->maxBytesPerBurst)
|
||||
{
|
||||
SC_METHOD(controllerMethod);
|
||||
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
|
||||
@@ -370,13 +371,6 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans,
|
||||
transToAcquire.payload = &trans;
|
||||
transToAcquire.time = sc_time_stamp() + delay;
|
||||
beginReqEvent.notify(delay);
|
||||
|
||||
DecodedAddress decodedAddress = addressDecoder.decodeAddress(transToAcquire.payload->get_address());
|
||||
ControllerExtension::setAutoExtension(*transToAcquire.payload, nextChannelPayloadIDToAppend++,
|
||||
Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup),
|
||||
Bank(decodedAddress.bank), Row(decodedAddress.row),
|
||||
Column(decodedAddress.column),
|
||||
transToAcquire.payload->get_data_length() / memSpec.bytesPerBeat);
|
||||
}
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
@@ -408,34 +402,62 @@ void Controller::manageRequests(const sc_time &delay)
|
||||
{
|
||||
if (transToAcquire.payload != nullptr && transToAcquire.time <= sc_time_stamp())
|
||||
{
|
||||
// Check size of transaction
|
||||
// unsigned numSubTrans = transToAcquire.payload->get_data_length() / memSpec.maxBytesPerBurst;
|
||||
// if (numSubTrans > 1)
|
||||
// {
|
||||
// // Split create child transactions
|
||||
// // Address decoding!!!
|
||||
// }
|
||||
|
||||
// TODO: here we assume that the scheduler always has space not only for a single burst transaction but for a maximum size transaction
|
||||
if (scheduler->hasBufferSpace())
|
||||
{
|
||||
NDEBUG_UNUSED(uint64_t id) = ControllerExtension::getChannelPayloadID(*transToAcquire.payload);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system.");
|
||||
//NDEBUG_UNUSED(uint64_t id) = ControllerExtension::getChannelPayloadID(*transToAcquire.payload);
|
||||
//PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system.");
|
||||
|
||||
if (totalNumberOfPayloads == 0)
|
||||
idleTimeCollector.end();
|
||||
totalNumberOfPayloads++;
|
||||
totalNumberOfPayloads++; // seems to be ok
|
||||
|
||||
Rank rank = ControllerExtension::getRank(*transToAcquire.payload);
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerExit();
|
||||
|
||||
ranksNumberOfPayloads[rank.ID()]++;
|
||||
|
||||
scheduler->storeRequest(*transToAcquire.payload);
|
||||
transToAcquire.payload->acquire();
|
||||
|
||||
Bank bank = ControllerExtension::getBank(*transToAcquire.payload);
|
||||
bankMachines[bank.ID()]->start();
|
||||
unsigned numChildTranses = transToAcquire.payload->get_data_length() / maxBytesPerBurst;
|
||||
if (numChildTranses <= 1)
|
||||
{
|
||||
DecodedAddress decodedAddress = addressDecoder.decodeAddress(transToAcquire.payload->get_address());
|
||||
ControllerExtension::setAutoExtension(*transToAcquire.payload, nextChannelPayloadIDToAppend++,
|
||||
Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup),
|
||||
Bank(decodedAddress.bank), Row(decodedAddress.row),
|
||||
Column(decodedAddress.column),
|
||||
transToAcquire.payload->get_data_length() / memSpec.bytesPerBeat);
|
||||
|
||||
Rank rank = Rank(decodedAddress.rank);
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerExit();
|
||||
ranksNumberOfPayloads[rank.ID()]++;
|
||||
|
||||
scheduler->storeRequest(*transToAcquire.payload);
|
||||
Bank bank = Bank(decodedAddress.bank);
|
||||
bankMachines[bank.ID()]->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
createChildTranses(*transToAcquire.payload, numChildTranses);
|
||||
const std::vector<tlm_generic_payload*>& childTranses =
|
||||
transToAcquire.payload->get_extension<ParentExtension>()->getChildTranses();
|
||||
for (auto* childTrans : childTranses)
|
||||
{
|
||||
DecodedAddress decodedAddress = addressDecoder.decodeAddress(childTrans->get_address());
|
||||
ControllerExtension::setAutoExtension(*childTrans, nextChannelPayloadIDToAppend,
|
||||
Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup),
|
||||
Bank(decodedAddress.bank), Row(decodedAddress.row),
|
||||
Column(decodedAddress.column),
|
||||
childTrans->get_data_length() / memSpec.bytesPerBeat);
|
||||
|
||||
Rank rank = Rank(decodedAddress.rank);
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerExit();
|
||||
ranksNumberOfPayloads[rank.ID()]++;
|
||||
|
||||
scheduler->storeRequest(*childTrans);
|
||||
Bank bank = Bank(decodedAddress.bank);
|
||||
bankMachines[bank.ID()]->start();
|
||||
}
|
||||
nextChannelPayloadIDToAppend++;
|
||||
}
|
||||
|
||||
transToAcquire.payload->set_response_status(TLM_OK_RESPONSE);
|
||||
tlm_phase bwPhase = END_REQ;
|
||||
@@ -463,7 +485,7 @@ void Controller::manageResponses()
|
||||
numberOfBeatsServed += ControllerExtension::getBurstLength(*transToRelease.payload);
|
||||
transToRelease.payload->release();
|
||||
transToRelease.payload = nullptr;
|
||||
totalNumberOfPayloads--;
|
||||
totalNumberOfPayloads--; // Important!! has to be done once for parent transaction
|
||||
|
||||
if (totalNumberOfPayloads == 0)
|
||||
{
|
||||
@@ -471,15 +493,42 @@ void Controller::manageResponses()
|
||||
}
|
||||
else
|
||||
{
|
||||
transToRelease.payload = respQueue->nextPayload();
|
||||
// TODO: hier fehlt noch was
|
||||
tlm_generic_payload* nextPayloadInQueue = respQueue->nextPayload();
|
||||
//transToRelease.payload = respQueue->nextPayload();
|
||||
|
||||
if (transToRelease.payload != nullptr)
|
||||
if (nextPayloadInQueue != nullptr)
|
||||
{
|
||||
// last payload was released in this cycle
|
||||
tlm_phase bwPhase = BEGIN_RESP;
|
||||
sc_time bwDelay = memSpec.tCK;
|
||||
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
|
||||
transToRelease.time = sc_max_time();
|
||||
if (ChildExtension::isChildTrans(*nextPayloadInQueue))
|
||||
{
|
||||
tlm_generic_payload& parentTrans = nextPayloadInQueue->get_extension<ChildExtension>()->getParentTrans();
|
||||
bool allChildTransesCompleted = parentTrans.get_extension<ParentExtension>()->notifyChildTransCompletion();
|
||||
if (allChildTransesCompleted)
|
||||
{
|
||||
parentTrans.get_extension<ParentExtension>()->releaseChildTranses();
|
||||
transToRelease.payload = &parentTrans;
|
||||
// last payload was released in this cycle
|
||||
tlm_phase bwPhase = BEGIN_RESP;
|
||||
sc_time bwDelay = memSpec.tCK;
|
||||
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
|
||||
transToRelease.time = sc_max_time();
|
||||
}
|
||||
else
|
||||
{
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transToRelease.payload = nextPayloadInQueue;
|
||||
// last payload was released in this cycle
|
||||
tlm_phase bwPhase = BEGIN_RESP;
|
||||
sc_time bwDelay = memSpec.tCK;
|
||||
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
|
||||
transToRelease.time = sc_max_time();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -492,19 +541,50 @@ void Controller::manageResponses()
|
||||
}
|
||||
else
|
||||
{
|
||||
transToRelease.payload = respQueue->nextPayload();
|
||||
tlm_generic_payload* nextPayloadInQueue = respQueue->nextPayload();
|
||||
|
||||
if (transToRelease.payload != nullptr)
|
||||
if (nextPayloadInQueue != nullptr)
|
||||
{
|
||||
tlm_phase bwPhase = BEGIN_RESP;
|
||||
sc_time bwDelay;
|
||||
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
|
||||
bwDelay = memSpec.tCK;
|
||||
else
|
||||
bwDelay = SC_ZERO_TIME;
|
||||
if (ChildExtension::isChildTrans(*nextPayloadInQueue))
|
||||
{
|
||||
tlm_generic_payload& parentTrans = nextPayloadInQueue->get_extension<ChildExtension>()->getParentTrans();
|
||||
bool allChildTransesCompleted = parentTrans.get_extension<ParentExtension>()->notifyChildTransCompletion();
|
||||
if (allChildTransesCompleted)
|
||||
{
|
||||
parentTrans.get_extension<ParentExtension>()->releaseChildTranses();
|
||||
transToRelease.payload = &parentTrans;
|
||||
// last payload was released in this cycle
|
||||
tlm_phase bwPhase = BEGIN_RESP;
|
||||
sc_time bwDelay;
|
||||
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
|
||||
bwDelay = memSpec.tCK;
|
||||
else
|
||||
bwDelay = SC_ZERO_TIME;
|
||||
|
||||
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
|
||||
transToRelease.time = sc_max_time();
|
||||
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
|
||||
transToRelease.time = sc_max_time();
|
||||
}
|
||||
else
|
||||
{
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transToRelease.payload = nextPayloadInQueue;
|
||||
// last payload was released in this cycle
|
||||
tlm_phase bwPhase = BEGIN_RESP;
|
||||
sc_time bwDelay;
|
||||
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
|
||||
bwDelay = memSpec.tCK;
|
||||
else
|
||||
bwDelay = SC_ZERO_TIME;
|
||||
|
||||
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
|
||||
transToRelease.time = sc_max_time();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -519,3 +599,52 @@ void Controller::sendToFrontend(tlm_generic_payload& payload, tlm_phase& phase,
|
||||
{
|
||||
tSocket->nb_transport_bw(payload, phase, delay);
|
||||
}
|
||||
|
||||
Controller::MemoryManager::~MemoryManager()
|
||||
{
|
||||
while (!freePayloads.empty())
|
||||
{
|
||||
tlm_generic_payload* payload = freePayloads.top();
|
||||
freePayloads.pop();
|
||||
payload->reset();
|
||||
delete payload;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tlm::tlm_generic_payload& Controller::MemoryManager::allocate()
|
||||
{
|
||||
if (freePayloads.empty())
|
||||
{
|
||||
return *new tlm_generic_payload(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
tlm_generic_payload* result = freePayloads.top();
|
||||
freePayloads.pop();
|
||||
return *result;
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::MemoryManager::free(tlm::tlm_generic_payload* payload)
|
||||
{
|
||||
freePayloads.push(payload);
|
||||
}
|
||||
|
||||
void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans, unsigned int numChildTranses)
|
||||
{
|
||||
std::vector<tlm_generic_payload*> childTranses;
|
||||
|
||||
for (unsigned childId = 0; childId < numChildTranses; childId++)
|
||||
{
|
||||
tlm_generic_payload& childTrans = memoryManager.allocate();
|
||||
childTrans.acquire();
|
||||
childTrans.set_command(parentTrans.get_command());
|
||||
childTrans.set_address(parentTrans.get_address() + childId * maxBytesPerBurst);
|
||||
childTrans.set_data_length(maxBytesPerBurst);
|
||||
childTrans.set_data_ptr(parentTrans.get_data_ptr() + childId * maxBytesPerBurst);
|
||||
ChildExtension::setExtension(childTrans, parentTrans);
|
||||
childTranses.push_back(&childTrans);
|
||||
}
|
||||
ParentExtension::setExtension(parentTrans, std::move(childTranses));
|
||||
}
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
#include <systemc>
|
||||
#include <tlm>
|
||||
@@ -100,6 +101,21 @@ private:
|
||||
void manageRequests(const sc_core::sc_time &delay);
|
||||
|
||||
sc_core::sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent;
|
||||
|
||||
const unsigned maxBytesPerBurst;
|
||||
|
||||
void createChildTranses(tlm::tlm_generic_payload& parentTrans, unsigned numChildTranses);
|
||||
|
||||
class MemoryManager : public tlm::tlm_mm_interface
|
||||
{
|
||||
public:
|
||||
~MemoryManager() override;
|
||||
tlm::tlm_generic_payload& allocate();
|
||||
void free(tlm::tlm_generic_payload* payload) override;
|
||||
|
||||
private:
|
||||
std::stack<tlm::tlm_generic_payload*> freePayloads;
|
||||
} memoryManager;
|
||||
};
|
||||
|
||||
#endif // CONTROLLER_H
|
||||
|
||||
Reference in New Issue
Block a user