diff --git a/DRAMSys/docs/images/PayloadExtension.svg b/DRAMSys/docs/images/PayloadExtension.svg new file mode 100644 index 00000000..fd0cb966 --- /dev/null +++ b/DRAMSys/docs/images/PayloadExtension.svg @@ -0,0 +1,2449 @@ + + + +Trace +file n +Trace +file +1 +Trace Player +1 +Trace Player n +Arbiter +Controller +Scheduler +ControllerCore +Controller +Scheduler +ControllerCore +DRAM +DRAM +GenerationExtension +sc +_ +time +( +timeOfGeneration +) +Generic Payload +Command +Address +Data pointer +Data length +Byte enable pointer +Byte enable length +Streaming width +DMI hint +Response status +Generic Payload +Command +Address +Data pointer +Data length +Byte enable pointer +Byte enable length +Streaming width +DMI hint +Response status +GenerationExtension +sc +_ +time +( +timeOfGeneration +) +DramExtension +Thread +Chanel +Bank +BankGroup +Row +Column +Burstlength +Generic Payload +Command +Address +Data pointer +Data length +Byte enable pointer +Byte enable length +Streaming width +DMI hint +Response status +GenerationExtension +sc +_ +time +( +timeOfGeneration +) +DramExtension +Thread +Chanel +Bank +BankGroup +Row +Column +Burstlength +Generic Payload +Command +Address +Data pointer +Data length +Byte enable pointer +Byte enable length +Streaming width +DMI hint +Response status +GenerationExtension +sc +_ +time +( +timeOfGeneration +) +DramExtension +Thread +Chanel +Bank +BankGroup +Row +Column +Burstlength + \ No newline at end of file diff --git a/DRAMSys/docs/images/PayloadMemoryManager.svg b/DRAMSys/docs/images/PayloadMemoryManager.svg new file mode 100644 index 00000000..3cf9fd46 --- /dev/null +++ b/DRAMSys/docs/images/PayloadMemoryManager.svg @@ -0,0 +1,988 @@ + + + +TracePlayer +BEGIN +_ +REQ +BEGIN +_ +REQ +END +_ +REQ +END +_ +REQ +BEGIN +_ +PRE +END +_ +PRE +BEGIN +_ +ACT +END +_ +ACT +BEGIN +_ +RD or BEGIN +_ +WR +END +_ +RD or END +_ +WR +BEGIN +_ +RESP +BEGIN +_ +RESP +END +_ +RESP +END +_ +RESP +Arbiter +Controller +DRAM +Allocate Payload +acquire +() +Set auto extension +( +GenerationExtension +) +acquire +() +Set auto extension +( +DramExtension +) +Get extension DramExtension +: +getBank +, +getRow +Get extension +DramExtension +: +getThread +Get extension +DramExtension +: +getBank +acquire +() +Get extension +DramExtension +: +getRow +release +() +release +() +release +() + \ No newline at end of file diff --git a/DRAMSys/docs/images/TransactionPhase.svg b/DRAMSys/docs/images/TransactionPhase.svg new file mode 100644 index 00000000..4a2973f4 --- /dev/null +++ b/DRAMSys/docs/images/TransactionPhase.svg @@ -0,0 +1,2026 @@ + + + +PEQFrontEnd +Scheduler +rowBufferIsOpen +( +Bank +) +Command +:: +Activate +FALSE +RowInRowBuffer += +getRow +( +Payload +) +TRUE +Command +:: +Precharge +FALSE +Command +:: +READ +Command +:: +WRITE +TRUE +& +READ +_ +COMMAND +TRUE +& +WRITE +_ +COMMAND +BEGIN +_ +ACT +BEGIN +_ +PRE +BEGIN +_ +RD +BEGIN +_ +WR +ControllerCore +( +PowerDownManager +, +RefreshManager +) +ControllerCorePEQ +Initiator Socket +Target Socket +Receive +nb +_ +transport +_ +fw +END +_ +ACT +END +_ +PRE +END +_ +RD +END +_ +WR +BEGIN +_ +ACT +BEGIN +_ +PRE +BEGIN +_ +RD +BEGIN +_ +WR +DramPEQ +nb +_ +transport +_ +bw +Controller +DRAM +Target Socket +nb +_ +transport +_ +fw +nb +_ +transport +_ +bw +From +/ +to Arbiter +END +_ +RD or END +_ +WR +END +_ +ACT or END +_ +PRE + \ No newline at end of file diff --git a/DRAMSys/simulator/src/simulation/Arbiter.h b/DRAMSys/simulator/src/simulation/Arbiter.h index d41273cd..6ddd56f1 100644 --- a/DRAMSys/simulator/src/simulation/Arbiter.h +++ b/DRAMSys/simulator/src/simulation/Arbiter.h @@ -101,10 +101,18 @@ private: std::vector tlmRecorders; + //used to map the transaction from devices to the arbiter's target socket ID. + std::map routeMap; + // Initiated by dram side // This function is called when an arbiter's initiator socket receives a transaction from a memory controller tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) { + // Check channel ID + assert((unsigned int)channelId < iSocket.size()); + if ((unsigned int)channelId != DramExtension::getExtension(payload).getChannel().ID()) { + SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted"); + } sc_time recTime = bwDelay + sc_time_stamp(); sc_time notDelay = bwDelay; @@ -122,12 +130,17 @@ private: // This function is called when an arbiter's target socket receives a transaction from a device tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay) { + assert ((unsigned int)id < tSocket.size()); if (phase == BEGIN_REQ) { + // Map the payload with socket id. + routeMap[&payload] = id; // In the begin request phase the socket ID is appended to the payload. // It will extracted from the payload and used later. appendDramExtension(id, payload); payload.acquire(); } else if (phase == END_RESP) { + // Erase before the payload is released. + routeMap.erase(&payload); payload.release(); } @@ -147,7 +160,9 @@ private: unsigned int initiatorSocket = DramExtension::getExtension(payload).getThread().ID()-1; unsigned int channelId = DramExtension::getExtension(payload).getChannel().ID(); - // TODO: here check if the channel and the initiatorSocket ID are valid. If not, the payload extension was corrupted. + // Check the valid range of initiatorSocket ID and channel Id + assert(initiatorSocket < Configuration::getInstance().NumberOfTracePlayers); + assert(channelId < Configuration::getInstance().NumberOfMemChannels); // Phases initiated by the intiator side from arbiter's point of view (devices performing memory requests to the arbiter) if (phase == BEGIN_REQ) { @@ -177,6 +192,10 @@ private: // Phases initiated by the target side from arbiter's point of view (memory side) else if (phase == END_REQ) { channelIsFree[channelId] = true; + // Validate the initiatorSocket ID + if ((int)initiatorSocket != routeMap[&payload]) { + SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted"); + } // The arbiter receives a transaction which phase is END_REQ from memory controller and forwards it to the requester device. sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME); @@ -190,6 +209,10 @@ private: channelIsFree[channelId] = false; } } else if (phase == BEGIN_RESP) { + // Validate the initiatorSocket ID + if ((int)initiatorSocket != routeMap[&payload]) { + SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted"); + } // The arbiter receives a transaction in BEGIN_RESP phase (that came from the memory side) and forwards it to the requester device if (receivedResponses[initiatorSocket].empty()) sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME); @@ -216,12 +239,35 @@ private: void appendDramExtension(int socketId, tlm_generic_payload& payload) { - // TODO: check if channel valid before appending. - // TODO: check if all parts of the decodedAddress are inside the valid range (devices should not perform invalid requests to the arbiter, right?). unsigned int burstlength = payload.get_streaming_width(); DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(payload.get_address()); - DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength); - payload.set_auto_extension(extension); + // Check the valid range of decodedAddress + if (addressIsValid(decodedAddress)) { + DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength); + payload.set_auto_extension(extension); + } else { + SC_REPORT_FATAL("Arbiter", "Decoded Address are not inside the valid range"); + } + } + + bool addressIsValid(DecodedAddress& decodedAddress) + { + if (decodedAddress.channel >= xmlAddressDecoder::getInstance().amount["channel"]) { + return false; + } + if (decodedAddress.bank >= xmlAddressDecoder::getInstance().amount["bank"]) { + return false; + } + if (decodedAddress.bankgroup > xmlAddressDecoder::getInstance().amount["bankgroup"]) { + return false; + } + if (decodedAddress.column >= xmlAddressDecoder::getInstance().amount["column"]) { + return false; + } + if (decodedAddress.row >= xmlAddressDecoder::getInstance().amount["row"]) { + return false; + } + return true; } void printDebugMessage(std::string message) diff --git a/README.md b/README.md index d2330084..c2949924 100644 --- a/README.md +++ b/README.md @@ -804,6 +804,24 @@ A description of the content each directory follows. - **traces**: trace files for simulations. They contain accesses to memory in certain known scenarios. +#### DRAMsys Diagrams + +- **Payload Extension information** + + GenerationExtension is added in TracePlayer and DramExtension is added in Arbiter. + + ![Payload Extension information](DRAMSys/docs/images/PayloadExtension.png) + +- **Transaction object with Memory Manager** + + The acquire method is called before passing the transaction object and the release method is called after the component is done with the transaction object. + + ![Payload Memory Manager](DRAMSys/docs/images/PayloadMemoryManager.png) + +- **Architecture of the backend TLM model** + + ![Architecture backend TLM](DRAMSys/docs/images/TransactionPhase.png) + #### References [1] TLM Modelling of 3D Stacked Wide I/O DRAM Subsystems, A Virtual Platform for Memory Controller Design Space Exploration