Fix unaligned bursts.
This commit is contained in:
@@ -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));
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user