Implement tCCDR for HBM2 and fix bug with SID
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"addressmapping": {
|
"addressmapping": {
|
||||||
|
"STACK_BIT":[
|
||||||
|
30
|
||||||
|
],
|
||||||
"PSEUDOCHANNEL_BIT":[
|
"PSEUDOCHANNEL_BIT":[
|
||||||
29
|
29
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"nbrOfBankGroups": 4,
|
"nbrOfBankGroups": 4,
|
||||||
"nbrOfBanks": 16,
|
"nbrOfBanks": 16,
|
||||||
"nbrOfColumns": 128,
|
"nbrOfColumns": 128,
|
||||||
|
"nbrOfStacks": 2,
|
||||||
"nbrOfPseudoChannels": 2,
|
"nbrOfPseudoChannels": 2,
|
||||||
"nbrOfRows": 32768,
|
"nbrOfRows": 32768,
|
||||||
"width": 64,
|
"width": 64,
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
"memtimingspec": {
|
"memtimingspec": {
|
||||||
"CCDL": 3,
|
"CCDL": 3,
|
||||||
"CCDS": 2,
|
"CCDS": 2,
|
||||||
|
"CCDR": 2,
|
||||||
"CKE": 8,
|
"CKE": 8,
|
||||||
"DQSCK": 1,
|
"DQSCK": 1,
|
||||||
"FAW": 16,
|
"FAW": 16,
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ void ControllerExtension::setAutoExtension(tlm::tlm_generic_payload& trans,
|
|||||||
{
|
{
|
||||||
extension->channelPayloadID = channelPayloadID;
|
extension->channelPayloadID = channelPayloadID;
|
||||||
extension->rank = rank;
|
extension->rank = rank;
|
||||||
|
extension->stack = stack;
|
||||||
extension->bankGroup = bankGroup;
|
extension->bankGroup = bankGroup;
|
||||||
extension->bank = bank;
|
extension->bank = bank;
|
||||||
extension->row = row;
|
extension->row = row;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ MemSpecHBM2::MemSpecHBM2(const Config::MemSpec& memSpec) :
|
|||||||
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") *
|
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") *
|
||||||
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
|
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
|
||||||
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
|
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
|
||||||
|
stacksPerChannel(memSpec.memarchitecturespec.entries.at("nbrOfStacks")),
|
||||||
tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")),
|
tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")),
|
||||||
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
|
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
|
||||||
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
|
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
|
||||||
@@ -75,6 +76,7 @@ MemSpecHBM2::MemSpecHBM2(const Config::MemSpec& memSpec) :
|
|||||||
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
|
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
|
||||||
tCCDL(tCK * memSpec.memtimingspec.entries.at("CCDL")),
|
tCCDL(tCK * memSpec.memtimingspec.entries.at("CCDL")),
|
||||||
tCCDS(tCK * memSpec.memtimingspec.entries.at("CCDS")),
|
tCCDS(tCK * memSpec.memtimingspec.entries.at("CCDS")),
|
||||||
|
tCCDR(tCK * memSpec.memtimingspec.entries.at("CCDR")),
|
||||||
tWTRL(tCK * memSpec.memtimingspec.entries.at("WTRL")),
|
tWTRL(tCK * memSpec.memtimingspec.entries.at("WTRL")),
|
||||||
tWTRS(tCK * memSpec.memtimingspec.entries.at("WTRS")),
|
tWTRS(tCK * memSpec.memtimingspec.entries.at("WTRS")),
|
||||||
tRTW(tCK * memSpec.memtimingspec.entries.at("RTW")),
|
tRTW(tCK * memSpec.memtimingspec.entries.at("RTW")),
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ public:
|
|||||||
explicit MemSpecHBM2(const Config::MemSpec& memSpec);
|
explicit MemSpecHBM2(const Config::MemSpec& memSpec);
|
||||||
|
|
||||||
// Memspec Variables:
|
// Memspec Variables:
|
||||||
|
const unsigned stacksPerChannel;
|
||||||
|
|
||||||
const sc_core::sc_time tDQSCK;
|
const sc_core::sc_time tDQSCK;
|
||||||
// sc_time tDQSQ; // TODO: check actual value of this parameter
|
// sc_time tDQSQ; // TODO: check actual value of this parameter
|
||||||
const sc_core::sc_time tRC;
|
const sc_core::sc_time tRC;
|
||||||
@@ -67,7 +69,7 @@ public:
|
|||||||
const sc_core::sc_time tWR;
|
const sc_core::sc_time tWR;
|
||||||
const sc_core::sc_time tCCDL;
|
const sc_core::sc_time tCCDL;
|
||||||
const sc_core::sc_time tCCDS;
|
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 tWTRL;
|
||||||
const sc_core::sc_time tWTRS;
|
const sc_core::sc_time tWTRS;
|
||||||
const sc_core::sc_time tRTW;
|
const sc_core::sc_time tRTW;
|
||||||
|
|||||||
@@ -542,7 +542,8 @@ void Controller::manageRequests(const sc_time& delay)
|
|||||||
{
|
{
|
||||||
if (transToAcquire.payload != nullptr && transToAcquire.arrival <= sc_time_stamp())
|
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 (scheduler->hasBufferSpace(requiredBufferEntries))
|
||||||
{
|
{
|
||||||
if (totalNumberOfPayloads == 0)
|
if (totalNumberOfPayloads == 0)
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ CheckerHBM2::CheckerHBM2(const MemSpecHBM2& memSpec) : memSpec(memSpec)
|
|||||||
nextCommandByBank.fill({BankVector<sc_time>(memSpec.banksPerChannel, SC_ZERO_TIME)});
|
nextCommandByBank.fill({BankVector<sc_time>(memSpec.banksPerChannel, SC_ZERO_TIME)});
|
||||||
nextCommandByBankGroup.fill({BankGroupVector<sc_time>(memSpec.bankGroupsPerChannel, SC_ZERO_TIME)});
|
nextCommandByBankGroup.fill({BankGroupVector<sc_time>(memSpec.bankGroupsPerChannel, SC_ZERO_TIME)});
|
||||||
nextCommandByRank.fill({RankVector<sc_time>(memSpec.ranksPerChannel, 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);
|
last4ActivatesOnRank = RankVector<std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||||
|
|
||||||
tBURST = ((memSpec.defaultBurstLength / memSpec.dataRate) * memSpec.tCK);
|
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);
|
Bank bank = ControllerExtension::getBank(payload);
|
||||||
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
||||||
Rank rank = ControllerExtension::getRank(payload);
|
Rank rank = ControllerExtension::getRank(payload);
|
||||||
|
Stack stack = ControllerExtension::getStack(payload);
|
||||||
|
|
||||||
|
|
||||||
sc_time earliestTimeToStart = sc_time_stamp();
|
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, nextCommandByBank[command][bank]);
|
||||||
earliestTimeToStart = std::max(earliestTimeToStart, nextCommandByBankGroup[command][bankGroup]);
|
earliestTimeToStart = std::max(earliestTimeToStart, nextCommandByBankGroup[command][bankGroup]);
|
||||||
earliestTimeToStart = std::max(earliestTimeToStart, nextCommandByRank[command][rank]);
|
earliestTimeToStart = std::max(earliestTimeToStart, nextCommandByRank[command][rank]);
|
||||||
|
earliestTimeToStart = std::max(earliestTimeToStart, nextCommandByStack[command][stack]);
|
||||||
if (command.isRasCommand())
|
if (command.isRasCommand())
|
||||||
{
|
{
|
||||||
earliestTimeToStart = std::max(earliestTimeToStart, nextCommandOnRasBus);
|
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 Bank bank = ControllerExtension::getBank(payload);
|
||||||
const BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
const BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
||||||
const Rank rank = ControllerExtension::getRank(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))
|
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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@@ -539,6 +573,36 @@ void CheckerHBM2::insert(Command command, const tlm_generic_payload& payload)
|
|||||||
earliestTimeToStart = std::max(earliestTimeToStart, constraint);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
#include "DRAMSys/configuration/memspec/MemSpecHBM2.h"
|
#include "DRAMSys/configuration/memspec/MemSpecHBM2.h"
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace DRAMSys
|
namespace DRAMSys
|
||||||
{
|
{
|
||||||
@@ -72,11 +71,14 @@ private:
|
|||||||
using BankGroupVector = ControllerVector<BankGroup, T>;
|
using BankGroupVector = ControllerVector<BankGroup, T>;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using RankVector = ControllerVector<Rank, T>;
|
using RankVector = ControllerVector<Rank, T>;
|
||||||
|
template<typename T>
|
||||||
|
using StackVector = ControllerVector<Stack, T>;
|
||||||
|
|
||||||
|
|
||||||
CommandArray<BankVector<sc_core::sc_time>> nextCommandByBank;
|
CommandArray<BankVector<sc_core::sc_time>> nextCommandByBank;
|
||||||
CommandArray<BankGroupVector<sc_core::sc_time>> nextCommandByBankGroup;
|
CommandArray<BankGroupVector<sc_core::sc_time>> nextCommandByBankGroup;
|
||||||
CommandArray<RankVector<sc_core::sc_time>> nextCommandByRank;
|
CommandArray<RankVector<sc_core::sc_time>> nextCommandByRank;
|
||||||
|
CommandArray<StackVector<sc_core::sc_time>> nextCommandByStack;
|
||||||
|
|
||||||
RankVector<std::queue<sc_core::sc_time>> last4ActivatesOnRank;
|
RankVector<std::queue<sc_core::sc_time>> last4ActivatesOnRank;
|
||||||
ControllerVector<Rank, unsigned> bankwiseRefreshCounter;
|
ControllerVector<Rank, unsigned> bankwiseRefreshCounter;
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"dataRate": 2,
|
"dataRate": 2,
|
||||||
"nbrOfBankGroups": 4,
|
"nbrOfBankGroups": 4,
|
||||||
"nbrOfBanks": 16,
|
"nbrOfBanks": 16,
|
||||||
|
"nbrOfStacks": 1,
|
||||||
"nbrOfColumns": 128,
|
"nbrOfColumns": 128,
|
||||||
"nbrOfPseudoChannels": 1,
|
"nbrOfPseudoChannels": 1,
|
||||||
"nbrOfChannels": 2,
|
"nbrOfChannels": 2,
|
||||||
@@ -75,6 +76,7 @@
|
|||||||
"memtimingspec": {
|
"memtimingspec": {
|
||||||
"CCDL": 3,
|
"CCDL": 3,
|
||||||
"CCDS": 2,
|
"CCDS": 2,
|
||||||
|
"CCDR": 2,
|
||||||
"CKE": 8,
|
"CKE": 8,
|
||||||
"DQSCK": 1,
|
"DQSCK": 1,
|
||||||
"FAW": 16,
|
"FAW": 16,
|
||||||
|
|||||||
Reference in New Issue
Block a user