Fix unaligned bursts.

This commit is contained in:
Lukas Steiner
2022-05-13 14:38:32 +02:00
parent 5d336fea45
commit 5237f70439
4 changed files with 65 additions and 26 deletions

View File

@@ -73,6 +73,7 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
ControllerIF(name, config), addressDecoder(addressDecoder),
thinkDelayFw(config.thinkDelayFw), thinkDelayBw(config.thinkDelayBw),
phyDelayFw(config.phyDelayFw), phyDelayBw(config.phyDelayBw),
minBytesPerBurst(config.memSpec->defaultBytesPerBurst),
maxBytesPerBurst(config.memSpec->maxBytesPerBurst)
{
SC_METHOD(controllerMethod);
@@ -402,20 +403,23 @@ void Controller::manageRequests(const sc_time &delay)
{
if (transToAcquire.payload != nullptr && transToAcquire.time <= sc_time_stamp())
{
// TODO: here we assume that the scheduler always has space not only for a single burst transaction but for a maximum size transaction
// 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.");
if (totalNumberOfPayloads == 0)
idleTimeCollector.end();
totalNumberOfPayloads++; // seems to be ok
transToAcquire.payload->acquire();
unsigned numChildTranses = transToAcquire.payload->get_data_length() / maxBytesPerBurst;
if (numChildTranses <= 1)
// Align address to minimum burst length
uint64_t alignedAddress = transToAcquire.payload->get_address() & ~(minBytesPerBurst - UINT64_C(1));
transToAcquire.payload->set_address(alignedAddress);
// continuous block of data that can be fetched with a single burst
if ((alignedAddress / maxBytesPerBurst)
== ((alignedAddress + transToAcquire.payload->get_data_length() - 1) / maxBytesPerBurst))
{
DecodedAddress decodedAddress = addressDecoder.decodeAddress(transToAcquire.payload->get_address());
ControllerExtension::setAutoExtension(*transToAcquire.payload, nextChannelPayloadIDToAppend++,
@@ -435,25 +439,18 @@ void Controller::manageRequests(const sc_time &delay)
}
else
{
createChildTranses(*transToAcquire.payload, numChildTranses);
createChildTranses(*transToAcquire.payload);
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);
Rank rank = ControllerExtension::getRank(*childTrans);
if (ranksNumberOfPayloads[rank.ID()] == 0)
powerDownManagers[rank.ID()]->triggerExit();
ranksNumberOfPayloads[rank.ID()]++;
scheduler->storeRequest(*childTrans);
Bank bank = Bank(decodedAddress.bank);
Bank bank = ControllerExtension::getBank(*childTrans);
bankMachines[bank.ID()]->start();
}
nextChannelPayloadIDToAppend++;
@@ -488,10 +485,11 @@ void Controller::manageResponses()
idleTimeCollector.start();
}
}
else
return; // END_RESP not completed
}
tlm_generic_payload* nextPayloadInRespQueue = respQueue->nextPayload();
if (nextPayloadInRespQueue != nullptr)
{
numberOfBeatsServed += ControllerExtension::getBurstLength(*nextPayloadInRespQueue);
@@ -576,20 +574,51 @@ void Controller::MemoryManager::free(tlm::tlm_generic_payload* payload)
freePayloads.push(payload);
}
void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans, unsigned int numChildTranses)
void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans)
{
std::vector<tlm_generic_payload*> childTranses;
uint64_t startAddress = parentTrans.get_address() & ~(maxBytesPerBurst - UINT64_C(1));
unsigned char* startDataPtr = parentTrans.get_data_ptr();
unsigned numChildTranses = parentTrans.get_data_length() / maxBytesPerBurst;
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_address(startAddress + childId * maxBytesPerBurst);
childTrans.set_data_length(maxBytesPerBurst);
childTrans.set_data_ptr(parentTrans.get_data_ptr() + childId * maxBytesPerBurst);
childTrans.set_data_ptr(startDataPtr + childId * maxBytesPerBurst);
ChildExtension::setExtension(childTrans, parentTrans);
childTranses.push_back(&childTrans);
}
if (startAddress != parentTrans.get_address())
{
tlm_generic_payload& firstChildTrans = *childTranses.front();
firstChildTrans.set_address(firstChildTrans.get_address() + minBytesPerBurst);
firstChildTrans.set_data_ptr(firstChildTrans.get_data_ptr() + minBytesPerBurst);
firstChildTrans.set_data_length(minBytesPerBurst);
tlm_generic_payload& lastChildTrans = memoryManager.allocate();
lastChildTrans.acquire();
lastChildTrans.set_command(parentTrans.get_command());
lastChildTrans.set_address(startAddress + numChildTranses * maxBytesPerBurst);
lastChildTrans.set_data_length(minBytesPerBurst);
lastChildTrans.set_data_ptr(startDataPtr + numChildTranses * maxBytesPerBurst);
ChildExtension::setExtension(lastChildTrans, parentTrans);
childTranses.push_back(&lastChildTrans);
}
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);
}
nextChannelPayloadIDToAppend++;
ParentExtension::setExtension(parentTrans, std::move(childTranses));
}

View File

@@ -102,9 +102,10 @@ private:
sc_core::sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent;
const unsigned minBytesPerBurst;
const unsigned maxBytesPerBurst;
void createChildTranses(tlm::tlm_generic_payload& parentTrans, unsigned numChildTranses);
void createChildTranses(tlm::tlm_generic_payload& parentTrans);
class MemoryManager : public tlm::tlm_mm_interface
{

View File

@@ -60,7 +60,8 @@ enum class RelevantAttributes
BankGroup = 0x02,
Bank = 0x04,
Row = 0x08,
Column = 0x10
Column = 0x10,
BurstLength = 0x20
};
inline RelevantAttributes operator|(RelevantAttributes a, RelevantAttributes b)
@@ -127,6 +128,11 @@ public:
return column;
}
unsigned int getBurstLength() const
{
return burstLength;
}
virtual RelevantAttributes getRelevantAttributes() const = 0;
virtual QString Name() const = 0;
@@ -376,7 +382,7 @@ protected:
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column;
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
@@ -398,7 +404,7 @@ protected:
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column;
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
@@ -420,7 +426,7 @@ protected:
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column;
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
@@ -442,7 +448,7 @@ protected:
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column;
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};

View File

@@ -149,6 +149,9 @@ void TransactionTreeWidget::TransactionTreeItem::AppendPhase(QTreeWidgetItem *pa
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::Column))
addMapping("Column", phase.getColumn());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::BurstLength))
addMapping("Burst Length", phase.getBurstLength());
}
}