diff --git a/configs/addressmapping/am_hbm2_8Gb_pc_brc.json b/configs/addressmapping/am_hbm2_8Gb_pc_brc.json index 87879fdc..f7bcb421 100644 --- a/configs/addressmapping/am_hbm2_8Gb_pc_brc.json +++ b/configs/addressmapping/am_hbm2_8Gb_pc_brc.json @@ -1,5 +1,8 @@ { "addressmapping": { + "STACK_BIT":[ + 30 + ], "PSEUDOCHANNEL_BIT":[ 29 ], diff --git a/configs/memspec/HBM2.json b/configs/memspec/HBM2.json index 1a351773..b4b696f6 100644 --- a/configs/memspec/HBM2.json +++ b/configs/memspec/HBM2.json @@ -6,6 +6,7 @@ "nbrOfBankGroups": 4, "nbrOfBanks": 16, "nbrOfColumns": 128, + "nbrOfStacks": 2, "nbrOfPseudoChannels": 2, "nbrOfRows": 32768, "width": 64, @@ -17,6 +18,7 @@ "memtimingspec": { "CCDL": 3, "CCDS": 2, + "CCDR": 2, "CKE": 8, "DQSCK": 1, "FAW": 16, diff --git a/src/libdramsys/DRAMSys/common/dramExtensions.cpp b/src/libdramsys/DRAMSys/common/dramExtensions.cpp index e8a31abd..d6aa97f9 100644 --- a/src/libdramsys/DRAMSys/common/dramExtensions.cpp +++ b/src/libdramsys/DRAMSys/common/dramExtensions.cpp @@ -191,6 +191,7 @@ void ControllerExtension::setAutoExtension(tlm::tlm_generic_payload& trans, { extension->channelPayloadID = channelPayloadID; extension->rank = rank; + extension->stack = stack; extension->bankGroup = bankGroup; extension->bank = bank; extension->row = row; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp index 0aeb6404..7ae285e7 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp @@ -59,6 +59,7 @@ MemSpecHBM2::MemSpecHBM2(const Config::MemSpec& memSpec) : memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") * memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"), memSpec.memarchitecturespec.entries.at("nbrOfDevices")), + stacksPerChannel(memSpec.memarchitecturespec.entries.at("nbrOfStacks")), tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")), tRC(tCK * memSpec.memtimingspec.entries.at("RC")), tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")), @@ -75,6 +76,7 @@ MemSpecHBM2::MemSpecHBM2(const Config::MemSpec& memSpec) : tWR(tCK * memSpec.memtimingspec.entries.at("WR")), tCCDL(tCK * memSpec.memtimingspec.entries.at("CCDL")), tCCDS(tCK * memSpec.memtimingspec.entries.at("CCDS")), + tCCDR(tCK * memSpec.memtimingspec.entries.at("CCDR")), tWTRL(tCK * memSpec.memtimingspec.entries.at("WTRL")), tWTRS(tCK * memSpec.memtimingspec.entries.at("WTRS")), tRTW(tCK * memSpec.memtimingspec.entries.at("RTW")), diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.h b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.h index b9a7e431..4ec04607 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.h +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.h @@ -50,6 +50,8 @@ public: explicit MemSpecHBM2(const Config::MemSpec& memSpec); // Memspec Variables: + const unsigned stacksPerChannel; + const sc_core::sc_time tDQSCK; // sc_time tDQSQ; // TODO: check actual value of this parameter const sc_core::sc_time tRC; @@ -67,7 +69,7 @@ public: const sc_core::sc_time tWR; const sc_core::sc_time tCCDL; const sc_core::sc_time tCCDS; - // sc_time tCCDR; // TODO: consecutive reads to different stack IDs + const sc_core::sc_time tCCDR; const sc_core::sc_time tWTRL; const sc_core::sc_time tWTRS; const sc_core::sc_time tRTW; diff --git a/src/libdramsys/DRAMSys/controller/Controller.cpp b/src/libdramsys/DRAMSys/controller/Controller.cpp index 8a509147..c826579c 100644 --- a/src/libdramsys/DRAMSys/controller/Controller.cpp +++ b/src/libdramsys/DRAMSys/controller/Controller.cpp @@ -542,7 +542,8 @@ void Controller::manageRequests(const sc_time& delay) { if (transToAcquire.payload != nullptr && transToAcquire.arrival <= sc_time_stamp()) { - unsigned requiredBufferEntries = transToAcquire.payload->get_data_length() / memSpec.maxBytesPerBurst; + unsigned requiredBufferEntries = + transToAcquire.payload->get_data_length() / memSpec.maxBytesPerBurst; if (scheduler->hasBufferSpace(requiredBufferEntries)) { if (totalNumberOfPayloads == 0) diff --git a/src/libdramsys/DRAMSys/controller/checker/CheckerHBM2.cpp b/src/libdramsys/DRAMSys/controller/checker/CheckerHBM2.cpp index 1fc8d352..ad30b77e 100644 --- a/src/libdramsys/DRAMSys/controller/checker/CheckerHBM2.cpp +++ b/src/libdramsys/DRAMSys/controller/checker/CheckerHBM2.cpp @@ -52,6 +52,7 @@ CheckerHBM2::CheckerHBM2(const MemSpecHBM2& memSpec) : memSpec(memSpec) nextCommandByBank.fill({BankVector(memSpec.banksPerChannel, SC_ZERO_TIME)}); nextCommandByBankGroup.fill({BankGroupVector(memSpec.bankGroupsPerChannel, SC_ZERO_TIME)}); nextCommandByRank.fill({RankVector(memSpec.ranksPerChannel, SC_ZERO_TIME)}); + nextCommandByStack.fill({StackVector(memSpec.stacksPerChannel, SC_ZERO_TIME)}); last4ActivatesOnRank = RankVector>(memSpec.ranksPerChannel); tBURST = ((memSpec.defaultBurstLength / memSpec.dataRate) * memSpec.tCK); @@ -71,6 +72,7 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic Bank bank = ControllerExtension::getBank(payload); BankGroup bankGroup = ControllerExtension::getBankGroup(payload); Rank rank = ControllerExtension::getRank(payload); + Stack stack = ControllerExtension::getStack(payload); sc_time earliestTimeToStart = sc_time_stamp(); @@ -79,6 +81,7 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic earliestTimeToStart = std::max(earliestTimeToStart, nextCommandByBank[command][bank]); earliestTimeToStart = std::max(earliestTimeToStart, nextCommandByBankGroup[command][bankGroup]); earliestTimeToStart = std::max(earliestTimeToStart, nextCommandByRank[command][rank]); + earliestTimeToStart = std::max(earliestTimeToStart, nextCommandByStack[command][stack]); if (command.isRasCommand()) { earliestTimeToStart = std::max(earliestTimeToStart, nextCommandOnRasBus); @@ -96,6 +99,7 @@ void CheckerHBM2::insert(Command command, const tlm_generic_payload& payload) const Bank bank = ControllerExtension::getBank(payload); const BankGroup bankGroup = ControllerExtension::getBankGroup(payload); const Rank rank = ControllerExtension::getRank(payload); + const Stack stack = ControllerExtension::getStack(payload); PRINTDEBUGMESSAGE("CheckerHBM2", "Changing state on bank " + std::to_string(static_cast(bank)) @@ -195,6 +199,36 @@ void CheckerHBM2::insert(Command command, const tlm_generic_payload& payload) earliestTimeToStart = std::max(earliestTimeToStart, constraint); } + // Channel (RD,RD) memSpec.tCCDR [] Different(level=) + { + const sc_time constraint = currentTime + memSpec.tCCDR; + for (unsigned int i = memSpec.stacksPerChannel * static_cast(0); i < memSpec.stacksPerChannel * (1 + static_cast(0)); i++) + { + Stack currentStack{i}; + + if (currentStack == stack) + continue; + + sc_time &earliestTimeToStart = nextCommandByStack[Command::RD][currentStack]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } + } + + // Channel (RD,RDA) memSpec.tCCDR [] Different(level=) + { + const sc_time constraint = currentTime + memSpec.tCCDR; + for (unsigned int i = memSpec.stacksPerChannel * static_cast(0); i < memSpec.stacksPerChannel * (1 + static_cast(0)); i++) + { + Stack currentStack{i}; + + if (currentStack == stack) + continue; + + sc_time &earliestTimeToStart = nextCommandByStack[Command::RDA][currentStack]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } + } + break; } @@ -539,6 +573,36 @@ void CheckerHBM2::insert(Command command, const tlm_generic_payload& payload) earliestTimeToStart = std::max(earliestTimeToStart, constraint); } + // Channel (RDA,RD) memSpec.tCCDR [] Different(level=) + { + const sc_time constraint = currentTime + memSpec.tCCDR; + for (unsigned int i = memSpec.stacksPerChannel * static_cast(0); i < memSpec.stacksPerChannel * (1 + static_cast(0)); i++) + { + Stack currentStack{i}; + + if (currentStack == stack) + continue; + + sc_time &earliestTimeToStart = nextCommandByStack[Command::RD][currentStack]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } + } + + // Channel (RDA,RDA) memSpec.tCCDR [] Different(level=) + { + const sc_time constraint = currentTime + memSpec.tCCDR; + for (unsigned int i = memSpec.stacksPerChannel * static_cast(0); i < memSpec.stacksPerChannel * (1 + static_cast(0)); i++) + { + Stack currentStack{i}; + + if (currentStack == stack) + continue; + + sc_time &earliestTimeToStart = nextCommandByStack[Command::RDA][currentStack]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } + } + break; } diff --git a/src/libdramsys/DRAMSys/controller/checker/CheckerHBM2.h b/src/libdramsys/DRAMSys/controller/checker/CheckerHBM2.h index 43c3e5e8..1e39ded0 100644 --- a/src/libdramsys/DRAMSys/controller/checker/CheckerHBM2.h +++ b/src/libdramsys/DRAMSys/controller/checker/CheckerHBM2.h @@ -41,7 +41,6 @@ #include "DRAMSys/configuration/memspec/MemSpecHBM2.h" #include -#include namespace DRAMSys { @@ -72,11 +71,14 @@ private: using BankGroupVector = ControllerVector; template using RankVector = ControllerVector; + template + using StackVector = ControllerVector; CommandArray> nextCommandByBank; CommandArray> nextCommandByBankGroup; CommandArray> nextCommandByRank; + CommandArray> nextCommandByStack; RankVector> last4ActivatesOnRank; ControllerVector bankwiseRefreshCounter; diff --git a/tests/tests_regression/HBM2/hbm2-example.json b/tests/tests_regression/HBM2/hbm2-example.json index a5f48df6..9690aea3 100644 --- a/tests/tests_regression/HBM2/hbm2-example.json +++ b/tests/tests_regression/HBM2/hbm2-example.json @@ -63,6 +63,7 @@ "dataRate": 2, "nbrOfBankGroups": 4, "nbrOfBanks": 16, + "nbrOfStacks": 1, "nbrOfColumns": 128, "nbrOfPseudoChannels": 1, "nbrOfChannels": 2, @@ -75,6 +76,7 @@ "memtimingspec": { "CCDL": 3, "CCDS": 2, + "CCDR": 2, "CKE": 8, "DQSCK": 1, "FAW": 16,