Implement tCCDR for HBM2 and fix bug with SID

This commit is contained in:
2025-02-21 14:14:21 +01:00
parent 5ab5a70d65
commit 6861576550
9 changed files with 82 additions and 3 deletions

View File

@@ -1,5 +1,8 @@
{
"addressmapping": {
"STACK_BIT":[
30
],
"PSEUDOCHANNEL_BIT":[
29
],

View File

@@ -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,

View File

@@ -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;

View File

@@ -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")),

View File

@@ -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;

View File

@@ -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)

View File

@@ -52,6 +52,7 @@ CheckerHBM2::CheckerHBM2(const MemSpecHBM2& memSpec) : memSpec(memSpec)
nextCommandByBank.fill({BankVector<sc_time>(memSpec.banksPerChannel, SC_ZERO_TIME)});
nextCommandByBankGroup.fill({BankGroupVector<sc_time>(memSpec.bankGroupsPerChannel, SC_ZERO_TIME)});
nextCommandByRank.fill({RankVector<sc_time>(memSpec.ranksPerChannel, SC_ZERO_TIME)});
nextCommandByStack.fill({StackVector<sc_time>(memSpec.stacksPerChannel, SC_ZERO_TIME)});
last4ActivatesOnRank = RankVector<std::queue<sc_time>>(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<std::size_t>(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=<ComponentLevel.Stack: 7>)
{
const sc_time constraint = currentTime + memSpec.tCCDR;
for (unsigned int i = memSpec.stacksPerChannel * static_cast<unsigned>(0); i < memSpec.stacksPerChannel * (1 + static_cast<unsigned>(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=<ComponentLevel.Stack: 7>)
{
const sc_time constraint = currentTime + memSpec.tCCDR;
for (unsigned int i = memSpec.stacksPerChannel * static_cast<unsigned>(0); i < memSpec.stacksPerChannel * (1 + static_cast<unsigned>(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=<ComponentLevel.Stack: 7>)
{
const sc_time constraint = currentTime + memSpec.tCCDR;
for (unsigned int i = memSpec.stacksPerChannel * static_cast<unsigned>(0); i < memSpec.stacksPerChannel * (1 + static_cast<unsigned>(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=<ComponentLevel.Stack: 7>)
{
const sc_time constraint = currentTime + memSpec.tCCDR;
for (unsigned int i = memSpec.stacksPerChannel * static_cast<unsigned>(0); i < memSpec.stacksPerChannel * (1 + static_cast<unsigned>(0)); i++)
{
Stack currentStack{i};
if (currentStack == stack)
continue;
sc_time &earliestTimeToStart = nextCommandByStack[Command::RDA][currentStack];
earliestTimeToStart = std::max(earliestTimeToStart, constraint);
}
}
break;
}

View File

@@ -41,7 +41,6 @@
#include "DRAMSys/configuration/memspec/MemSpecHBM2.h"
#include <queue>
#include <vector>
namespace DRAMSys
{
@@ -72,11 +71,14 @@ private:
using BankGroupVector = ControllerVector<BankGroup, T>;
template<typename T>
using RankVector = ControllerVector<Rank, T>;
template<typename T>
using StackVector = ControllerVector<Stack, T>;
CommandArray<BankVector<sc_core::sc_time>> nextCommandByBank;
CommandArray<BankGroupVector<sc_core::sc_time>> nextCommandByBankGroup;
CommandArray<RankVector<sc_core::sc_time>> nextCommandByRank;
CommandArray<StackVector<sc_core::sc_time>> nextCommandByStack;
RankVector<std::queue<sc_core::sc_time>> last4ActivatesOnRank;
ControllerVector<Rank, unsigned> bankwiseRefreshCounter;

View File

@@ -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,