From 5237f70439bc067aabb008a24ed599bb6fd66757 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 13 May 2022 14:38:32 +0200 Subject: [PATCH] Fix unaligned bursts. --- DRAMSys/library/src/controller/Controller.cpp | 69 +++++++++++++------ DRAMSys/library/src/controller/Controller.h | 3 +- .../businessObjects/phases/phase.h | 16 +++-- .../presentation/transactiontreewidget.cpp | 3 + 4 files changed, 65 insertions(+), 26 deletions(-) diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 248efc6f..d97a252b 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -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& childTranses = transToAcquire.payload->get_extension()->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 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)); } \ No newline at end of file diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index 2432099d..58ebbd69 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -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 { diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index ebfb6f8f..e6fab72a 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -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; } }; diff --git a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp index b20ba0a0..b8d5137c 100644 --- a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp +++ b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp @@ -149,6 +149,9 @@ void TransactionTreeWidget::TransactionTreeItem::AppendPhase(QTreeWidgetItem *pa if (static_cast(phase.getRelevantAttributes() & RelevantAttributes::Column)) addMapping("Column", phase.getColumn()); + + if (static_cast(phase.getRelevantAttributes() & RelevantAttributes::BurstLength)) + addMapping("Burst Length", phase.getBurstLength()); } }