Merge branch 'cmdmux_rascas' into 'develop'

Add special command muxes for standards with separate RAS and CAS command buses (HBM).

See merge request ems/astdm/dram.sys!275
This commit is contained in:
Lukas Steiner
2021-04-23 08:56:11 +00:00
10 changed files with 275 additions and 41 deletions

View File

@@ -95,3 +95,8 @@ sc_time MemSpec::getRefreshIntervalSB() const
SC_REPORT_FATAL("MemSpec", "Same bank refresh not supported");
return SC_ZERO_TIME;
}
bool MemSpec::hasRasAndCasBus() const
{
return false;
}

View File

@@ -77,6 +77,8 @@ public:
virtual sc_time getRefreshIntervalPB() const;
virtual sc_time getRefreshIntervalSB() const;
virtual bool hasRasAndCasBus() const;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const = 0;
virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0;

View File

@@ -94,6 +94,11 @@ sc_time MemSpecHBM2::getRefreshIntervalPB() const
return tREFISB;
}
bool MemSpecHBM2::hasRasAndCasBus() const
{
return true;
}
sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload &payload) const
{
if (command == Command::PRE || command == Command::PREA)

View File

@@ -83,6 +83,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getRefreshIntervalPB() const override;
virtual bool hasRasAndCasBus() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;

View File

@@ -112,9 +112,19 @@ Controller::Controller(sc_module_name name) :
scheduler = new SchedulerFrFcfsGrp();
if (config.cmdMux == Configuration::CmdMux::Oldest)
cmdMux = new CmdMuxOldest();
{
if (memSpec->hasRasAndCasBus())
cmdMux = new CmdMuxOldestRasCas();
else
cmdMux = new CmdMuxOldest();
}
else if (config.cmdMux == Configuration::CmdMux::Strict)
cmdMux = new CmdMuxStrict();
{
if (memSpec->hasRasAndCasBus())
cmdMux = new CmdMuxStrictRasCas();
else
cmdMux = new CmdMuxStrict();
}
if (config.respQueue == Configuration::RespQueue::Fifo)
respQueue = new RespQueueFifo();

View File

@@ -45,7 +45,7 @@ class CmdMuxIF
{
public:
virtual ~CmdMuxIF() {}
virtual CommandTuple::Type selectCommand(ReadyCommands &) = 0;
virtual CommandTuple::Type selectCommand(const ReadyCommands &) = 0;
};
#endif // CMDMUXIF_H

View File

@@ -40,7 +40,7 @@ using namespace tlm;
CmdMuxOldest::CmdMuxOldest() : memSpec(Configuration::getInstance().memSpec) {}
CommandTuple::Type CmdMuxOldest::selectCommand(ReadyCommands &readyCommands)
CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommands)
{
auto result = readyCommands.cend();
uint64_t lastPayloadID = UINT64_MAX;
@@ -51,7 +51,7 @@ CommandTuple::Type CmdMuxOldest::selectCommand(ReadyCommands &readyCommands)
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it)) - memSpec->tCK;
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
@@ -60,13 +60,116 @@ CommandTuple::Type CmdMuxOldest::selectCommand(ReadyCommands &readyCommands)
lastPayloadID = newPayloadID;
result = it;
}
else if (newTimestamp == lastTimestamp)
else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID))
{
if (newPayloadID < lastPayloadID)
{
lastPayloadID = newPayloadID;
result = it;
}
lastPayloadID = newPayloadID;
result = it;
}
}
if (result != readyCommands.cend() &&
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
return *result;
else
return CommandTuple::Type(Command::NOP, nullptr, sc_max_time());
}
CmdMuxOldestRasCas::CmdMuxOldestRasCas() : memSpec(Configuration::getInstance().memSpec)
{
readyRasCommands.reserve(memSpec->numberOfBanks);
readyCasCommands.reserve(memSpec->numberOfBanks);
readyRasCasCommands.reserve(2);
}
CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyCommands)
{
readyRasCommands.clear();
readyCasCommands.clear();
for (auto it : readyCommands)
{
if (isRasCommand(std::get<CommandTuple::Command>(it)))
readyRasCommands.emplace_back(it);
else
readyCasCommands.emplace_back(it);
}
auto result = readyCommands.cend();
auto resultRas = readyRasCommands.cend();
auto resultCas = readyCasCommands.cend();
uint64_t lastPayloadID = UINT64_MAX;
uint64_t newPayloadID;
sc_time lastTimestamp = sc_max_time();
sc_time newTimestamp;
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
lastTimestamp = newTimestamp;
lastPayloadID = newPayloadID;
resultRas = it;
}
else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID))
{
lastPayloadID = newPayloadID;
resultRas = it;
}
}
lastPayloadID = UINT64_MAX;
lastTimestamp = sc_max_time();
for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
lastTimestamp = newTimestamp;
lastPayloadID = newPayloadID;
resultCas = it;
}
else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID))
{
lastPayloadID = newPayloadID;
resultCas = it;
}
}
readyRasCasCommands.clear();
if (resultRas != readyRasCommands.cend())
readyRasCasCommands.emplace_back(*resultRas);
if (resultCas != readyCasCommands.cend())
readyRasCasCommands.emplace_back(*resultCas);
lastPayloadID = UINT64_MAX;
lastTimestamp = sc_max_time();
for (auto it = readyRasCasCommands.cbegin(); it != readyRasCasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it);
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
lastTimestamp = newTimestamp;
lastPayloadID = newPayloadID;
result = it;
}
else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID))
{
lastPayloadID = newPayloadID;
result = it;
}
}

View File

@@ -42,10 +42,24 @@ class CmdMuxOldest : public CmdMuxIF
{
public:
CmdMuxOldest();
CommandTuple::Type selectCommand(ReadyCommands &);
virtual CommandTuple::Type selectCommand(const ReadyCommands &) override;
private:
const MemSpec *memSpec;
};
class CmdMuxOldestRasCas : public CmdMuxIF
{
public:
CmdMuxOldestRasCas();
virtual CommandTuple::Type selectCommand(const ReadyCommands &) override;
private:
const MemSpec *memSpec;
ReadyCommands readyRasCommands;
ReadyCommands readyCasCommands;
ReadyCommands readyRasCasCommands;
};
#endif // CMDMUXOLDEST_H

View File

@@ -40,7 +40,7 @@ using namespace tlm;
CmdMuxStrict::CmdMuxStrict() : memSpec(Configuration::getInstance().memSpec) {}
CommandTuple::Type CmdMuxStrict::selectCommand(ReadyCommands &readyCommands)
CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommands)
{
auto result = readyCommands.cend();
uint64_t lastPayloadID = UINT64_MAX;
@@ -51,44 +51,24 @@ CommandTuple::Type CmdMuxStrict::selectCommand(ReadyCommands &readyCommands)
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it)) - memSpec->tCK;
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
if (isCasCommand(std::get<CommandTuple::Command>(*it)))
{
if (newPayloadID == nextPayloadID)
{
lastTimestamp = newTimestamp;
lastPayloadID = newPayloadID;
result = it;
}
}
else
if (isRasCommand(std::get<CommandTuple::Command>(*it)) || newPayloadID == nextPayloadID)
{
lastTimestamp = newTimestamp;
lastPayloadID = newPayloadID;
result = it;
}
}
}
else if (newTimestamp == lastTimestamp)
else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID))
{
if (isCasCommand(std::get<CommandTuple::Command>(*it)))
if (isRasCommand(std::get<CommandTuple::Command>(*it)) || newPayloadID == nextPayloadID)
{
if ((newPayloadID < lastPayloadID) && (newPayloadID == nextPayloadID))
{
lastPayloadID = newPayloadID;
result = it;
}
}
else
{
if (newPayloadID < lastPayloadID)
{
lastPayloadID = newPayloadID;
result = it;
}
lastPayloadID = newPayloadID;
result = it;
}
}
}
@@ -103,3 +83,102 @@ CommandTuple::Type CmdMuxStrict::selectCommand(ReadyCommands &readyCommands)
else
return CommandTuple::Type(Command::NOP, nullptr, sc_max_time());
}
CmdMuxStrictRasCas::CmdMuxStrictRasCas() : memSpec(Configuration::getInstance().memSpec)
{
readyRasCommands.reserve(memSpec->numberOfBanks);
readyCasCommands.reserve(memSpec->numberOfBanks);
readyRasCasCommands.reserve(2);
}
CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyCommands)
{
readyRasCommands.clear();
readyCasCommands.clear();
for (auto it : readyCommands)
{
if (isRasCommand(std::get<CommandTuple::Command>(it)))
readyRasCommands.emplace_back(it);
else
readyCasCommands.emplace_back(it);
}
auto result = readyCommands.cend();
auto resultRas = readyRasCommands.cend();
auto resultCas = readyCasCommands.cend();
uint64_t lastPayloadID = UINT64_MAX;
uint64_t newPayloadID;
sc_time lastTimestamp = sc_max_time();
sc_time newTimestamp;
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
lastTimestamp = newTimestamp;
lastPayloadID = newPayloadID;
resultRas = it;
}
else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID))
{
lastPayloadID = newPayloadID;
resultRas = it;
}
}
for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); it++)
{
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
if (newPayloadID == nextPayloadID)
{
resultCas = it;
break;
}
}
readyRasCasCommands.clear();
if (resultRas != readyRasCommands.cend())
readyRasCasCommands.emplace_back(*resultRas);
if (resultCas != readyCasCommands.cend())
readyRasCasCommands.emplace_back(*resultCas);
lastPayloadID = UINT64_MAX;
lastTimestamp = sc_max_time();
for (auto it = readyRasCasCommands.cbegin(); it != readyRasCasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it);
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
lastTimestamp = newTimestamp;
lastPayloadID = newPayloadID;
result = it;
}
else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID))
{
lastPayloadID = newPayloadID;
result = it;
}
}
if (result != readyCommands.cend() &&
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
{
if (isCasCommand(std::get<CommandTuple::Command>(*result)))
nextPayloadID++;
return *result;
}
else
return CommandTuple::Type(Command::NOP, nullptr, sc_max_time());
}

View File

@@ -42,11 +42,25 @@ class CmdMuxStrict : public CmdMuxIF
{
public:
CmdMuxStrict();
CommandTuple::Type selectCommand(ReadyCommands &);
virtual CommandTuple::Type selectCommand(const ReadyCommands &) override;
private:
uint64_t nextPayloadID = 1;
const MemSpec *memSpec;
};
class CmdMuxStrictRasCas : public CmdMuxIF
{
public:
CmdMuxStrictRasCas();
virtual CommandTuple::Type selectCommand(const ReadyCommands &) override;
private:
uint64_t nextPayloadID = 1;
const MemSpec *memSpec;
ReadyCommands readyRasCommands;
ReadyCommands readyCasCommands;
ReadyCommands readyRasCasCommands;
};
#endif // CMDMUXSTRICT_H