Merge branch 'develop' into 'master'
Command mux with more freedom, small bugfixes. See merge request ems/astdm/dram.sys!265
This commit is contained in:
@@ -140,7 +140,7 @@ std::string parseString(json &obj, std::string name)
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
}
|
||||
|
||||
void setUpDummy(tlm_generic_payload &payload, Rank rank, Bank bank)
|
||||
void setUpDummy(tlm_generic_payload &payload, uint64_t payloadID, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
{
|
||||
payload.set_address(bank.getStartAddress());
|
||||
payload.set_command(TLM_READ_COMMAND);
|
||||
@@ -149,6 +149,6 @@ void setUpDummy(tlm_generic_payload &payload, Rank rank, Bank bank)
|
||||
payload.set_dmi_allowed(false);
|
||||
payload.set_byte_enable_length(0);
|
||||
payload.set_streaming_width(0);
|
||||
payload.set_extension(new DramExtension(Thread(UINT_MAX), rank, BankGroup(0),
|
||||
bank, Row(0), Column(0), 0, 0));
|
||||
payload.set_extension(new DramExtension(Thread(UINT_MAX), rank, bankgroup,
|
||||
bank, Row(0), Column(0), 0, payloadID));
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ unsigned int parseUint(nlohmann::json &obj, std::string name);
|
||||
double parseUdouble(nlohmann::json &obj, std::string name);
|
||||
std::string parseString(nlohmann::json &obj, std::string name);
|
||||
|
||||
void setUpDummy(tlm::tlm_generic_payload &payload, Rank rank = Rank(0), Bank bank = Bank(0));
|
||||
void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t payloadID, Rank rank = Rank(0), BankGroup bankgroup = BankGroup(0), Bank bank = Bank(0));
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||
|
||||
@@ -44,12 +44,9 @@ BankMachine::BankMachine(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
|
||||
bankgroup = BankGroup(bank.ID() / memSpec->banksPerGroup);
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> BankMachine::getNextCommand()
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time> BankMachine::getNextCommand()
|
||||
{
|
||||
if (sc_time_stamp() == timeToSchedule)
|
||||
return std::pair<Command, tlm_generic_payload *>(nextCommand, currentPayload);
|
||||
else
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
return std::tuple<Command, tlm_generic_payload *, sc_time>(nextCommand, currentPayload, timeToSchedule);
|
||||
}
|
||||
|
||||
void BankMachine::updateState(Command command)
|
||||
@@ -124,6 +121,7 @@ BankMachineOpen::BankMachineOpen(SchedulerIF *scheduler, CheckerIF *checker, Ban
|
||||
sc_time BankMachineOpen::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
nextCommand = Command::NOP;
|
||||
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
@@ -134,30 +132,26 @@ sc_time BankMachineOpen::start()
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
{
|
||||
if (DramExtension::getRow(currentPayload) == currentRow) // row hit
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
nextCommand = Command::RD;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (!blocked) // row miss
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
nextCommand = Command::PRE;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
@@ -169,6 +163,7 @@ BankMachineClosed::BankMachineClosed(SchedulerIF *scheduler, CheckerIF *checker,
|
||||
sc_time BankMachineClosed::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
nextCommand = Command::NOP;
|
||||
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
@@ -179,23 +174,19 @@ sc_time BankMachineClosed::start()
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
nextCommand = Command::RDA;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
return timeToSchedule;
|
||||
}
|
||||
@@ -206,6 +197,7 @@ BankMachineOpenAdaptive::BankMachineOpenAdaptive(SchedulerIF *scheduler, Checker
|
||||
sc_time BankMachineOpenAdaptive::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
nextCommand = Command::NOP;
|
||||
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
@@ -216,8 +208,8 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
{
|
||||
@@ -226,38 +218,27 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, currentRow))
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
nextCommand = Command::RDA;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
nextCommand = Command::RD;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
}
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (!blocked) // row miss
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
nextCommand = Command::PRE;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
@@ -269,6 +250,7 @@ BankMachineClosedAdaptive::BankMachineClosedAdaptive(SchedulerIF *scheduler, Che
|
||||
sc_time BankMachineClosedAdaptive::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
nextCommand = Command::NOP;
|
||||
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
@@ -279,8 +261,8 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
{
|
||||
@@ -289,38 +271,27 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
if (scheduler->hasFurtherRowHit(bank, currentRow))
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
nextCommand = Command::RD;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
nextCommand = Command::RDA;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
}
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (!blocked) // row miss TODO: remove this, can never happen
|
||||
{
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
nextCommand = Command::PRE;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ class BankMachine
|
||||
public:
|
||||
virtual ~BankMachine() {}
|
||||
virtual sc_time start() = 0;
|
||||
std::pair<Command, tlm::tlm_generic_payload *> getNextCommand();
|
||||
std::tuple<Command, tlm::tlm_generic_payload *, sc_time> getNextCommand();
|
||||
void updateState(Command);
|
||||
void block();
|
||||
|
||||
@@ -74,7 +74,7 @@ protected:
|
||||
tlm::tlm_generic_payload *currentPayload = nullptr;
|
||||
SchedulerIF *scheduler;
|
||||
CheckerIF *checker;
|
||||
Command nextCommand;
|
||||
Command nextCommand = Command::NOP;
|
||||
BmState currentState = BmState::Precharged;
|
||||
Row currentRow;
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
|
||||
@@ -239,29 +239,27 @@ void Controller::controllerMethod()
|
||||
it->start();
|
||||
|
||||
// (5) Choose one request and send it to DRAM
|
||||
std::pair<Command, tlm_generic_payload *> commandPair;
|
||||
std::vector<std::pair<Command, tlm_generic_payload *>> readyCommands;
|
||||
// (5.1) Check for power-down commands (PDEA/PDEP/SREFEN or PDXA/PDXP/SREFEX)
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time> commandTuple;
|
||||
std::list<std::tuple<Command, tlm_generic_payload *, sc_time>> readyCommands;
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
commandPair = powerDownManagers[rankID]->getNextCommand();
|
||||
if (commandPair.second != nullptr)
|
||||
readyCommands.push_back(commandPair);
|
||||
// (5.1) Check for power-down commands (PDEA/PDEP/SREFEN or PDXA/PDXP/SREFEX)
|
||||
commandTuple = powerDownManagers[rankID]->getNextCommand();
|
||||
if (std::get<0>(commandTuple) != Command::NOP)
|
||||
readyCommands.push_back(commandTuple);
|
||||
else
|
||||
{
|
||||
// (5.2) Check for refresh commands (PREA/PRE or REFA/REFB)
|
||||
commandPair = refreshManagers[rankID]->getNextCommand();
|
||||
if (commandPair.second != nullptr)
|
||||
readyCommands.push_back(commandPair);
|
||||
else
|
||||
commandTuple = refreshManagers[rankID]->getNextCommand();
|
||||
if (std::get<0>(commandTuple) != Command::NOP)
|
||||
readyCommands.push_back(commandTuple);
|
||||
|
||||
// (5.3) Check for bank commands (PRE, ACT, RD/RDA or WR/WRA)
|
||||
for (auto it : bankMachinesOnRank[rankID])
|
||||
{
|
||||
// (5.3) Check for bank commands (PRE, ACT, RD/RDA or WR/WRA)
|
||||
for (auto it : bankMachinesOnRank[rankID])
|
||||
{
|
||||
commandPair = it->getNextCommand();
|
||||
if (commandPair.second != nullptr)
|
||||
readyCommands.push_back(commandPair);
|
||||
}
|
||||
commandTuple = it->getNextCommand();
|
||||
if (std::get<0>(commandTuple) != Command::NOP)
|
||||
readyCommands.push_back(commandTuple);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,29 +267,29 @@ void Controller::controllerMethod()
|
||||
bool readyCmdBlocked = false;
|
||||
if (!readyCommands.empty())
|
||||
{
|
||||
commandPair = cmdMux->selectCommand(readyCommands);
|
||||
if (commandPair.second != nullptr) // can happen with FIFO strict
|
||||
commandTuple = cmdMux->selectCommand(readyCommands);
|
||||
if (std::get<0>(commandTuple) != Command::NOP) // can happen with FIFO strict
|
||||
{
|
||||
Rank rank = DramExtension::getRank(commandPair.second);
|
||||
BankGroup bankgroup = DramExtension::getBankGroup(commandPair.second);
|
||||
Bank bank = DramExtension::getBank(commandPair.second);
|
||||
Rank rank = DramExtension::getRank(std::get<1>(commandTuple));
|
||||
BankGroup bankgroup = DramExtension::getBankGroup(std::get<1>(commandTuple));
|
||||
Bank bank = DramExtension::getBank(std::get<1>(commandTuple));
|
||||
|
||||
if (isRankCommand(commandPair.first))
|
||||
if (isRankCommand(std::get<0>(commandTuple)))
|
||||
{
|
||||
for (auto it : bankMachinesOnRank[rank.ID()])
|
||||
it->updateState(commandPair.first);
|
||||
it->updateState(std::get<0>(commandTuple));
|
||||
}
|
||||
else
|
||||
bankMachines[bank.ID()]->updateState(commandPair.first);
|
||||
bankMachines[bank.ID()]->updateState(std::get<0>(commandTuple));
|
||||
|
||||
refreshManagers[rank.ID()]->updateState(commandPair.first, commandPair.second);
|
||||
powerDownManagers[rank.ID()]->updateState(commandPair.first);
|
||||
checker->insert(commandPair.first, rank, bankgroup, bank);
|
||||
refreshManagers[rank.ID()]->updateState(std::get<0>(commandTuple));
|
||||
powerDownManagers[rank.ID()]->updateState(std::get<0>(commandTuple));
|
||||
checker->insert(std::get<0>(commandTuple), rank, bankgroup, bank);
|
||||
|
||||
if (isCasCommand(commandPair.first))
|
||||
if (isCasCommand(std::get<0>(commandTuple)))
|
||||
{
|
||||
scheduler->removeRequest(commandPair.second);
|
||||
respQueue->insertPayload(commandPair.second, memSpec->getIntervalOnDataStrobe(commandPair.first).end);
|
||||
scheduler->removeRequest(std::get<1>(commandTuple));
|
||||
respQueue->insertPayload(std::get<1>(commandTuple), memSpec->getIntervalOnDataStrobe(std::get<0>(commandTuple)).end);
|
||||
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
@@ -302,7 +300,7 @@ void Controller::controllerMethod()
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerEntry();
|
||||
|
||||
sendToDram(commandPair.first, commandPair.second);
|
||||
sendToDram(std::get<0>(commandTuple), std::get<1>(commandTuple));
|
||||
}
|
||||
else
|
||||
readyCmdBlocked = true;
|
||||
|
||||
@@ -65,9 +65,9 @@ public:
|
||||
virtual ~Controller();
|
||||
|
||||
protected:
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &);
|
||||
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &);
|
||||
virtual unsigned int transport_dbg(tlm::tlm_generic_payload &);
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &) override;
|
||||
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &) override;
|
||||
virtual unsigned int transport_dbg(tlm::tlm_generic_payload &) override;
|
||||
|
||||
virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase);
|
||||
virtual void sendToDram(Command, tlm::tlm_generic_payload *);
|
||||
|
||||
@@ -60,35 +60,35 @@ public:
|
||||
/ Configuration::getInstance().memSpec->dataRate
|
||||
* Configuration::getInstance().memSpec->tCK;
|
||||
|
||||
double bandwidth = (activeTime / sc_time_stamp() * 100);
|
||||
double bandwidthWoIdle = ((activeTime) / (sc_time_stamp() - idleTimeCollector.getIdleTime()) * 100);
|
||||
double bandwidth = activeTime / sc_time_stamp();
|
||||
double bandwidthWoIdle = activeTime / (sc_time_stamp() - idleTimeCollector.getIdleTime());
|
||||
|
||||
double maxBandwidth = (
|
||||
// fCK in Mhz e.g. 800 [MHz]:
|
||||
(1000000 / Configuration::getInstance().memSpec->tCK.to_double())
|
||||
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
|
||||
(1000 / Configuration::getInstance().memSpec->tCK.to_double())
|
||||
// DataRate e.g. 2
|
||||
* Configuration::getInstance().memSpec->dataRate
|
||||
// BusWidth e.g. 8 or 64
|
||||
* Configuration::getInstance().memSpec->bitWidth
|
||||
// Number of devices on a DIMM e.g. 8
|
||||
* Configuration::getInstance().memSpec->numberOfDevicesOnDIMM ) / ( 1024 );
|
||||
* Configuration::getInstance().memSpec->numberOfDevicesOnDIMM );
|
||||
|
||||
std::cout << name() << std::string(" Total Time: ")
|
||||
<< sc_time_stamp().to_string()
|
||||
<< std::endl;
|
||||
std::cout << name() << std::string(" AVG BW: ")
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< ((bandwidth / 100) * maxBandwidth)
|
||||
<< " Gibit/s (" << bandwidth << " %)"
|
||||
<< (bandwidth * maxBandwidth)
|
||||
<< " Gb/s (" << (bandwidth * 100) << " %)"
|
||||
<< std::endl;
|
||||
std::cout << name() << std::string(" AVG BW\\IDLE: ")
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< ((bandwidthWoIdle / 100) * maxBandwidth)
|
||||
<< " Gibit/s (" << bandwidthWoIdle << " %)"
|
||||
<< (bandwidthWoIdle * maxBandwidth)
|
||||
<< " Gb/s (" << (bandwidthWoIdle * 100) << " %)"
|
||||
<< endl;
|
||||
std::cout << name() << std::string(" MAX BW: ")
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< maxBandwidth << " Gibit/s"
|
||||
<< maxBandwidth << " Gb/s"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,17 +44,17 @@ public:
|
||||
ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder) :
|
||||
Controller(name), tlmRecorder(tlmRecorder) {}
|
||||
|
||||
protected:
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans,
|
||||
tlm::tlm_phase &phase, sc_time &delay) override;
|
||||
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans,
|
||||
tlm::tlm_phase &phase, sc_time &delay) override;
|
||||
|
||||
virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase) override;
|
||||
virtual void sendToDram(Command, tlm::tlm_generic_payload *) override;
|
||||
|
||||
private:
|
||||
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans,
|
||||
tlm::tlm_phase &phase, sc_time &delay) override;
|
||||
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans,
|
||||
tlm::tlm_phase &phase, sc_time &delay) override;
|
||||
|
||||
void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase) override;
|
||||
void sendToDram(Command, tlm::tlm_generic_payload *) override;
|
||||
|
||||
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time delay);
|
||||
|
||||
TlmRecorder *tlmRecorder;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,17 +35,18 @@
|
||||
#ifndef CMDMUXIF_H
|
||||
#define CMDMUXIF_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include "../Command.h"
|
||||
|
||||
class CmdMuxIF
|
||||
{
|
||||
public:
|
||||
virtual ~CmdMuxIF() {}
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *>
|
||||
selectCommand(std::vector<std::pair<Command, tlm::tlm_generic_payload *>> &) = 0;
|
||||
virtual std::tuple<Command, tlm::tlm_generic_payload *, sc_time>
|
||||
selectCommand(std::list<std::tuple<Command, tlm::tlm_generic_payload *, sc_time>> &) = 0;
|
||||
};
|
||||
|
||||
#endif // CMDMUXIF_H
|
||||
|
||||
@@ -38,23 +38,30 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
std::pair<Command, tlm_generic_payload *>
|
||||
CmdMuxOldest::selectCommand(std::vector<std::pair<Command, tlm_generic_payload *>> &readyCommands)
|
||||
{
|
||||
auto it = readyCommands.begin();
|
||||
auto result = it;
|
||||
unsigned lastPayloadID = DramExtension::getPayloadID(it->second);
|
||||
it++;
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time>
|
||||
CmdMuxOldest::selectCommand(std::list<std::tuple<Command, tlm_generic_payload *, sc_time>> &readyCommands)
|
||||
{
|
||||
readyCommands.remove_if([](std::tuple<Command, tlm_generic_payload *, sc_time> element){return std::get<2>(element) != sc_time_stamp();});
|
||||
|
||||
while (it != readyCommands.end())
|
||||
if (!readyCommands.empty())
|
||||
{
|
||||
unsigned newPayloadID = DramExtension::getPayloadID(it->second);
|
||||
if (newPayloadID < lastPayloadID)
|
||||
{
|
||||
lastPayloadID = newPayloadID;
|
||||
result = it;
|
||||
}
|
||||
auto it = readyCommands.begin();
|
||||
auto result = it;
|
||||
uint64_t lastPayloadID = DramExtension::getPayloadID(std::get<1>(*it));
|
||||
it++;
|
||||
|
||||
while (it != readyCommands.end())
|
||||
{
|
||||
uint64_t newPayloadID = DramExtension::getPayloadID(std::get<1>(*it));
|
||||
if (newPayloadID < lastPayloadID)
|
||||
{
|
||||
lastPayloadID = newPayloadID;
|
||||
result = it;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
return *result;
|
||||
}
|
||||
return *result;
|
||||
else
|
||||
return std::tuple<Command, tlm_generic_payload *, sc_time>(Command::NOP, nullptr, sc_max_time());
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
class CmdMuxOldest : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
selectCommand(std::vector<std::pair<Command, tlm::tlm_generic_payload *>> &);
|
||||
std::tuple<Command, tlm::tlm_generic_payload *, sc_time>
|
||||
selectCommand(std::list<std::tuple<Command, tlm::tlm_generic_payload *, sc_time>> &);
|
||||
};
|
||||
|
||||
#endif // CMDMUXOLDEST_H
|
||||
|
||||
@@ -38,24 +38,29 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
std::pair<Command, tlm_generic_payload *>
|
||||
CmdMuxStrict::selectCommand(std::vector<std::pair<Command, tlm_generic_payload *>> &readyCommands)
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time>
|
||||
CmdMuxStrict::selectCommand(std::list<std::tuple<Command, tlm_generic_payload *, sc_time>> &readyCommands)
|
||||
{
|
||||
for (auto it : readyCommands)
|
||||
readyCommands.remove_if([](std::tuple<Command, tlm_generic_payload *, sc_time> element){return std::get<2>(element) != sc_time_stamp();});
|
||||
|
||||
if (!readyCommands.empty())
|
||||
{
|
||||
if (isCasCommand(it.first))
|
||||
for (auto it : readyCommands)
|
||||
{
|
||||
if (DramExtension::getPayloadID(it.second) == nextPayloadID)
|
||||
if (isCasCommand(std::get<0>(it)))
|
||||
{
|
||||
nextPayloadID++;
|
||||
return it;
|
||||
if (DramExtension::getPayloadID(std::get<1>(it)) == nextPayloadID)
|
||||
{
|
||||
nextPayloadID++;
|
||||
return it;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto it : readyCommands)
|
||||
{
|
||||
if (isRasCommand(std::get<0>(it)))
|
||||
return it;
|
||||
}
|
||||
}
|
||||
for (auto it : readyCommands)
|
||||
{
|
||||
if (isRasCommand(it.first))
|
||||
return it;
|
||||
}
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
return std::tuple<Command, tlm_generic_payload *, sc_time>(Command::NOP, nullptr, sc_max_time());
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
class CmdMuxStrict : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
selectCommand(std::vector<std::pair<Command, tlm::tlm_generic_payload *>> &);
|
||||
std::tuple<Command, tlm::tlm_generic_payload *, sc_time>
|
||||
selectCommand(std::list<std::tuple<Command, tlm::tlm_generic_payload *, sc_time>> &);
|
||||
|
||||
private:
|
||||
uint64_t nextPayloadID = 0;
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> PowerDownManagerDummy::getNextCommand()
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time> PowerDownManagerDummy::getNextCommand()
|
||||
{
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
return std::tuple<Command, tlm_generic_payload *, sc_time>(Command::NOP, nullptr, sc_max_time());
|
||||
}
|
||||
|
||||
sc_time PowerDownManagerDummy::start()
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
virtual void triggerExit() override {}
|
||||
virtual void triggerInterruption() override {}
|
||||
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::tuple<Command, tlm::tlm_generic_payload *, sc_time> getNextCommand() override;
|
||||
virtual void updateState(Command) override {}
|
||||
virtual sc_time start() override;
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
virtual void triggerExit() = 0;
|
||||
virtual void triggerInterruption() = 0;
|
||||
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() = 0;
|
||||
virtual std::tuple<Command, tlm::tlm_generic_payload *, sc_time> getNextCommand() = 0;
|
||||
virtual void updateState(Command) = 0;
|
||||
virtual sc_time start() = 0;
|
||||
};
|
||||
|
||||
@@ -40,7 +40,7 @@ using namespace tlm;
|
||||
PowerDownManagerStaggered::PowerDownManagerStaggered(Rank rank, CheckerIF *checker)
|
||||
: rank(rank), checker(checker)
|
||||
{
|
||||
setUpDummy(powerDownPayload, rank);
|
||||
setUpDummy(powerDownPayload, UINT64_MAX, rank);
|
||||
}
|
||||
|
||||
void PowerDownManagerStaggered::triggerEntry()
|
||||
@@ -69,17 +69,15 @@ void PowerDownManagerStaggered::triggerInterruption()
|
||||
exitTriggered = true;
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> PowerDownManagerStaggered::getNextCommand()
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time> PowerDownManagerStaggered::getNextCommand()
|
||||
{
|
||||
if (sc_time_stamp() == timeToSchedule)
|
||||
return std::pair<Command, tlm_generic_payload *>(nextCommand, &powerDownPayload);
|
||||
else
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
return std::tuple<Command, tlm_generic_payload *, sc_time>(nextCommand, &powerDownPayload, timeToSchedule);
|
||||
}
|
||||
|
||||
sc_time PowerDownManagerStaggered::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
nextCommand = Command::NOP;
|
||||
|
||||
if (exitTriggered)
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
virtual void triggerExit() override;
|
||||
virtual void triggerInterruption() override;
|
||||
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::tuple<Command, tlm::tlm_generic_payload *, sc_time> getNextCommand() override;
|
||||
virtual void updateState(Command) override;
|
||||
virtual sc_time start() override;
|
||||
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
CheckerIF *checker;
|
||||
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
Command nextCommand;
|
||||
Command nextCommand = Command::NOP;
|
||||
|
||||
bool controllerIdle = true;
|
||||
bool entryTriggered = true;
|
||||
|
||||
@@ -50,27 +50,26 @@ RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankM
|
||||
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->banksPerRank);
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++)
|
||||
{
|
||||
setUpDummy(refreshPayloads[bankID], rank, bankMachines[bankID]->getBank());
|
||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachines[bankID]->getBankGroup(), bankMachines[bankID]->getBank());
|
||||
allBankMachines.push_back(bankMachines[bankID]);
|
||||
}
|
||||
remainingBankMachines = allBankMachines;
|
||||
currentBankMachine = *remainingBankMachines.begin();
|
||||
|
||||
maxPostponed = config.refreshMaxPostponed * memSpec->banksPerRank;
|
||||
maxPulledin = -(config.refreshMaxPulledin * memSpec->banksPerRank);
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> RefreshManagerBankwise::getNextCommand()
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time> RefreshManagerBankwise::getNextCommand()
|
||||
{
|
||||
if (sc_time_stamp() == timeToSchedule)
|
||||
return std::pair<Command, tlm_generic_payload *>
|
||||
(nextCommand, &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->banksPerRank]);
|
||||
else
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
return std::tuple<Command, tlm_generic_payload *, sc_time>
|
||||
(nextCommand, &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->banksPerRank], timeToSchedule);
|
||||
}
|
||||
|
||||
sc_time RefreshManagerBankwise::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
nextCommand = Command::NOP;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger)
|
||||
{
|
||||
@@ -86,13 +85,14 @@ sc_time RefreshManagerBankwise::start()
|
||||
|
||||
if (state == RmState::Regular)
|
||||
{
|
||||
currentIterator = remainingBankMachines.begin();
|
||||
currentBankMachine = *remainingBankMachines.begin();
|
||||
bool forcedRefresh = (flexibilityCounter == maxPostponed);
|
||||
bool allBanksBusy = true;
|
||||
|
||||
if (!skipSelection)
|
||||
{
|
||||
currentIterator = remainingBankMachines.begin();
|
||||
currentBankMachine = *remainingBankMachines.begin();
|
||||
|
||||
for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++)
|
||||
{
|
||||
if ((*it)->isIdle())
|
||||
@@ -168,7 +168,7 @@ sc_time RefreshManagerBankwise::start()
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::updateState(Command command, tlm_generic_payload *payload)
|
||||
void RefreshManagerBankwise::updateState(Command command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
|
||||
@@ -48,9 +48,9 @@ class RefreshManagerBankwise final : public RefreshManagerIF
|
||||
public:
|
||||
RefreshManagerBankwise(std::vector<BankMachine *> &, PowerDownManagerIF *, Rank, CheckerIF *);
|
||||
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::tuple<Command, tlm::tlm_generic_payload *, sc_time> getNextCommand() override;
|
||||
virtual sc_time start() override;
|
||||
virtual void updateState(Command, tlm::tlm_generic_payload *) override;
|
||||
virtual void updateState(Command) override;
|
||||
|
||||
private:
|
||||
enum class RmState {Regular, Pulledin} state = RmState::Regular;
|
||||
@@ -62,7 +62,7 @@ private:
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
Rank rank;
|
||||
CheckerIF *checker;
|
||||
Command nextCommand;
|
||||
Command nextCommand = Command::NOP;
|
||||
|
||||
std::list<BankMachine *> remainingBankMachines;
|
||||
std::list<BankMachine *> allBankMachines;
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> RefreshManagerDummy::getNextCommand()
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time> RefreshManagerDummy::getNextCommand()
|
||||
{
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
return std::tuple<Command, tlm_generic_payload *, sc_time>(Command::NOP, nullptr, sc_max_time());
|
||||
}
|
||||
|
||||
sc_time RefreshManagerDummy::start()
|
||||
|
||||
@@ -44,9 +44,9 @@
|
||||
class RefreshManagerDummy final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::tuple<Command, tlm::tlm_generic_payload *, sc_time> getNextCommand() override;
|
||||
virtual sc_time start() override;
|
||||
virtual void updateState(Command, tlm::tlm_generic_payload *) override {}
|
||||
virtual void updateState(Command) override {}
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGERDUMMY_H
|
||||
|
||||
@@ -45,9 +45,9 @@ class RefreshManagerIF
|
||||
public:
|
||||
virtual ~RefreshManagerIF() {}
|
||||
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() = 0;
|
||||
virtual std::tuple<Command, tlm::tlm_generic_payload *, sc_time> getNextCommand() = 0;
|
||||
virtual sc_time start() = 0;
|
||||
virtual void updateState(Command, tlm::tlm_generic_payload *) = 0;
|
||||
virtual void updateState(Command) = 0;
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGERIF_H
|
||||
|
||||
@@ -46,23 +46,21 @@ RefreshManagerRankwise::RefreshManagerRankwise(std::vector<BankMachine *> &bankM
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
timeForNextTrigger = memSpec->getRefreshIntervalAB();
|
||||
setUpDummy(refreshPayload, rank);
|
||||
setUpDummy(refreshPayload, 0, rank);
|
||||
|
||||
maxPostponed = config.refreshMaxPostponed;
|
||||
maxPulledin = -config.refreshMaxPulledin;
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> RefreshManagerRankwise::getNextCommand()
|
||||
std::tuple<Command, tlm_generic_payload *, sc_time> RefreshManagerRankwise::getNextCommand()
|
||||
{
|
||||
if (sc_time_stamp() == timeToSchedule)
|
||||
return std::pair<Command, tlm_generic_payload *>(nextCommand, &refreshPayload);
|
||||
else
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
return std::tuple<Command, tlm_generic_payload *, sc_time>(nextCommand, &refreshPayload, timeToSchedule);
|
||||
}
|
||||
|
||||
sc_time RefreshManagerRankwise::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
nextCommand = Command::NOP;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger)
|
||||
{
|
||||
@@ -130,7 +128,7 @@ sc_time RefreshManagerRankwise::start()
|
||||
}
|
||||
else
|
||||
{
|
||||
// nextCommand stays Command::REFA
|
||||
nextCommand = Command::REFA;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
return timeToSchedule;
|
||||
}
|
||||
@@ -140,7 +138,7 @@ sc_time RefreshManagerRankwise::start()
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
|
||||
void RefreshManagerRankwise::updateState(Command command, tlm_generic_payload *)
|
||||
void RefreshManagerRankwise::updateState(Command command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
|
||||
@@ -46,9 +46,9 @@ class RefreshManagerRankwise final : public RefreshManagerIF
|
||||
public:
|
||||
RefreshManagerRankwise(std::vector<BankMachine *> &, PowerDownManagerIF *, Rank, CheckerIF *);
|
||||
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::tuple<Command, tlm::tlm_generic_payload *, sc_time> getNextCommand() override;
|
||||
virtual sc_time start() override;
|
||||
virtual void updateState(Command, tlm::tlm_generic_payload *) override;
|
||||
virtual void updateState(Command) override;
|
||||
|
||||
private:
|
||||
enum class RmState {Regular, Pulledin} state = RmState::Regular;
|
||||
@@ -60,7 +60,7 @@ private:
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
Rank rank;
|
||||
CheckerIF *checker;
|
||||
Command nextCommand;
|
||||
Command nextCommand = Command::NOP;
|
||||
|
||||
unsigned activatedBanks = 0;
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
tlm::tlm_sync_enum nb_transport_bw(int channelId, tlm::tlm_generic_payload &payload,
|
||||
tlm::tlm_phase &phase, sc_time &bwDelay);
|
||||
|
||||
virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans);
|
||||
unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans);
|
||||
|
||||
void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase);
|
||||
|
||||
|
||||
@@ -143,19 +143,27 @@ DRAMSys::~DRAMSys()
|
||||
|
||||
void DRAMSys::logo()
|
||||
{
|
||||
#define REDTXT(s) std::string("\033[0;31m" + std::string(s) + "\033[0m")
|
||||
#define BOLDBLUETXT(s) std::string("\033[1;34m" + std::string(s) + "\033[0m")
|
||||
std::cout << std::endl;
|
||||
std::cout << REDTXT(" |||") << std::endl;
|
||||
std::cout << REDTXT(" +---+ Microelectronic Systems") << std::endl;
|
||||
std::cout << REDTXT("=| |= Design Research Group") << std::endl;
|
||||
std::cout << REDTXT("=| |= ") << BOLDBLUETXT("Technische Universität Kaiserslautern")
|
||||
#define GREENTXT(s) std::string(("\u001b[38;5;28m"+std::string((s))+"\033[0m"))
|
||||
#define DGREENTXT(s) std::string(("\u001b[38;5;22m"+std::string((s))+"\033[0m"))
|
||||
#define LGREENTXT(s) std::string(("\u001b[38;5;82m"+std::string((s))+"\033[0m"))
|
||||
#define BLACKTXT(s) std::string(("\u001b[38;5;232m"+std::string((s))+"\033[0m"))
|
||||
#define BOLDTXT(s) std::string(("\033[1;37m"+std::string((s))+"\033[0m"))
|
||||
cout << std::endl
|
||||
<< BLACKTXT("■ ■ ")<< DGREENTXT("■ ")
|
||||
<< BOLDTXT("DRAMSys4.0, Copyright (c) 2020")
|
||||
<< std::endl
|
||||
<< BLACKTXT("■ ") << DGREENTXT("■ ") << GREENTXT("■ ")
|
||||
<< "Technische Universitaet Kaiserslautern,"
|
||||
<< std::endl
|
||||
<< DGREENTXT("■ ") << GREENTXT("■ ") << LGREENTXT("■ " )
|
||||
<< "Fraunhofer IESE"
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
std::cout << REDTXT(" +---+ ") << std::endl;
|
||||
std::cout << REDTXT(" ||| ") << "DRAMSys4.0" << std::endl;
|
||||
std::cout << std::endl;
|
||||
#undef REDTXT
|
||||
#undef BOLDBLUETXT
|
||||
#undef GREENTXT
|
||||
#undef DGREENTXT
|
||||
#undef LGREENTXT
|
||||
#undef BLACKTXT
|
||||
#undef BOLDTXT
|
||||
}
|
||||
|
||||
void DRAMSys::setupDebugManager(const std::string &traceName __attribute__((unused)))
|
||||
|
||||
@@ -48,8 +48,9 @@ class DramRecordable final : public BaseDram
|
||||
public:
|
||||
DramRecordable(sc_module_name, TlmRecorder *);
|
||||
SC_HAS_PROCESS(DramRecordable);
|
||||
virtual ~DramRecordable() {}
|
||||
|
||||
virtual void reportPower();
|
||||
virtual void reportPower() override;
|
||||
|
||||
private:
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload,
|
||||
|
||||
28
README.md
28
README.md
@@ -31,6 +31,18 @@ A UML diagram of the software architecture is presented below; different compone
|
||||
|
||||
<img src="DRAMSys/docs/images/dramsys_uml.png" alt="UML" />
|
||||
|
||||
## Trace Analyzer Consulting and Custom-Tailored Modifications
|
||||
|
||||
To provide better analysis capabilities for DRAM subsystem design space exploration than the usual performance-related outputs to the console, DRAMSys offers the Trace Analyzer.
|
||||
|
||||
All requests, responses and DRAM commands can be recorded in an SQLite trace database during a simulation and visualized with the tool afterwards. An evaluation of the trace databases can be performed with the powerful Python interface of the Trace Analyzer. Different metrics are described as SQL statements and formulas in Python, which can be customized or extended without recompilation.
|
||||
|
||||
The Trace Analyzer's main window is shown below.
|
||||
|
||||
If you are interested in the database recording feature and the Trace Analyzer, if you need support on how to setup DRAMSys in a virtual platform of your company, or if you require custom modifications of the simulator please contact [Matthias Jung](mailto:matthias.jung@iese.fraunhofer.de).
|
||||
|
||||

|
||||
|
||||
## Basic Setup
|
||||
|
||||
Start using DRAMSys by cloning the repository.
|
||||
@@ -204,7 +216,7 @@ The content of [ddr3.json](DRAMSys/library/resources/configs/simulator/ddr3.json
|
||||
}
|
||||
```
|
||||
|
||||
- *SimulationName* (boolean)
|
||||
- *SimulationName* (string)
|
||||
- Give the name of the simulation for distinguishing from other simulations.
|
||||
- *Debug* (boolean)
|
||||
- true: enables debug output on console (only supported by a debug build)
|
||||
@@ -342,7 +354,7 @@ An example follows.
|
||||
|
||||
## DRAMSys with Thermal Simulation
|
||||
|
||||
The thermal simulation is performed by a **3D-ICE** [8] server accessed through the network. Therefore users interested in thermal simulation during their DRAMSys simulations need to make sure they have a 3D-ICE server up and running before starting. For more information about 3D-ICE visit the [official website](https://www.epfl.ch/labs/esl/open-source-software-projects/3d-ice/).
|
||||
The thermal simulation is performed by a **3D-ICE** [8] server accessed through the network. Therefore users interested in thermal simulation during their DRAMSys simulations need to make sure they have a 3D-ICE server up and running before starting. For more information about 3D-ICE visit the [official website](https://www.epfl.ch/labs/esl/open-source-software-projects/3d-ice/). An example video that visualizes the results of a thermal simulation is provided on [Youtube](https://www.youtube.com/watch?v=Eacsq71hHtY).
|
||||
|
||||
#### Installing 3D-ICE
|
||||
|
||||
@@ -506,18 +518,6 @@ The content of [config.json](DRAMSys/library/resources/configs/thermalsim/config
|
||||
- true: generate power map files during thermal simulation
|
||||
- false: do not generate power map files during thermal simulation
|
||||
|
||||
## Trace Analyzer Consulting and Custom-Tailored Modifications
|
||||
|
||||
To provide better analysis capabilities for DRAM subsystem design space exploration than the usual performance-related outputs to the console, DRAMSys offers the Trace Analyzer.
|
||||
|
||||
All requests, responses and DRAM commands can be recorded in an SQLite trace database during a simulation and visualized with the tool afterwards. An evaluation of the trace databases can be performed with the powerful Python interface of the Trace Analyzer. Different metrics are described as SQL statements and formulas in Python, which can be customized or extended without recompilation.
|
||||
|
||||
The Trace Analyzer's main window is shown below.
|
||||
|
||||
If you are interested in the database recording feature and the Trace Analyzer, if you need support on how to setup DRAMSys in a virtual platform of your company, or if you require custom modifications of the simulator please contact [Matthias Jung](mailto:matthias.jung@iese.fraunhofer.de).
|
||||
|
||||

|
||||
|
||||
## Acknowledgements
|
||||
|
||||
The development of DRAMSys was supported by the German Research Foundation (DFG) as part of the priority program [Dependable Embedded Systems SPP1500](http://spp1500.itec.kit.edu) and the DFG grant no. [WE2442/10-1](https://www.uni-kl.de/en/3d-dram/). Furthermore, it was supported within the Fraunhofer and DFG cooperation program (grant no. [WE2442/14-1](https://www.iese.fraunhofer.de/en/innovation_trends/autonomous-systems/memtonomy.html)) and by the [Fraunhofer High Performance Center for Simulation- and Software-Based Innovation](https://www.leistungszentrum-simulation-software.de/en.html). Special thanks go to all listed contributors for their work and commitment during seven years of development.
|
||||
|
||||
Reference in New Issue
Block a user