diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index e29200c0..c2c9fcaa 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -46,15 +46,16 @@ sc_time BankMachine::startBankMachine() return SC_ZERO_TIME; } sc_time delay; + DramExtension extension = DramExtension::getExtension(currentPayload); if (currentState == BmState::Precharged) { delay = checker->delayToSatisfyConstraints(Command::ACT, bank); nextCommand = Command::ACT; + nextRow = extension.getRow(); timeToSchedule = sc_time_stamp() + delay; } else if (currentState == BmState::Activated) { - DramExtension extension = DramExtension::getExtension(currentPayload); if (extension.getRow() == currentRow) // row hit { if (currentPayload->get_command() == TLM_READ_COMMAND) @@ -76,8 +77,8 @@ sc_time BankMachine::startBankMachine() { delay = checker->delayToSatisfyConstraints(Command::PRE, bank); nextCommand = Command::PRE; + nextRow = extension.getRow(); timeToSchedule = sc_time_stamp() + delay; - currentRow = extension.getRow(); } } return delay; @@ -94,7 +95,10 @@ std::pair BankMachine::getNextCommand() void BankMachine::updateState(Command command) { if (command == Command::ACT) + { currentState = BmState::Activated; + currentRow = nextRow; + } else if (command == Command::PRE) currentState = BmState::Precharged; else if (command == Command::RD || command == Command::WR) diff --git a/DRAMSys/library/src/controller/BankMachine.h b/DRAMSys/library/src/controller/BankMachine.h index 77eeec72..4574bfa2 100644 --- a/DRAMSys/library/src/controller/BankMachine.h +++ b/DRAMSys/library/src/controller/BankMachine.h @@ -70,8 +70,9 @@ private: tlm_generic_payload *currentPayload = nullptr; BmState currentState = BmState::Precharged; Bank bank; - Row currentRow = Row(0); - Command nextCommand = Command::NOP; + Row currentRow; + Row nextRow; + Command nextCommand; sc_time timeToSchedule = SC_ZERO_TIME; SchedulerIF *scheduler; CheckerIF *checker; diff --git a/DRAMSys/library/src/controller/ControllerNew.cpp b/DRAMSys/library/src/controller/ControllerNew.cpp index 5d8d95ec..2a4562f4 100644 --- a/DRAMSys/library/src/controller/ControllerNew.cpp +++ b/DRAMSys/library/src/controller/ControllerNew.cpp @@ -56,10 +56,50 @@ ControllerNew::ControllerNew(sc_module_name name) : for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++) bankMachines[Bank(bankID)] = new BankMachine(scheduler, checker, Bank(bankID)); commandMux = new CmdMuxStrict(); + + startBandwidthIdleCollector(); } ControllerNew::~ControllerNew() { + endBandwithIdleCollector(); + + sc_time activeTime = numberOfTransactionsServed + * Configuration::getInstance().memSpec->BurstLength + / Configuration::getInstance().memSpec->DataRate + * Configuration::getInstance().memSpec->clk; + + double bandwidth = (activeTime / sc_time_stamp() * 100); + double bandwidth_IDLE = ((activeTime) / (sc_time_stamp() - idleTime) * 100); + + double maxBandwidth = ( + // clk in Mhz e.g. 800 [MHz]: + (1000000 / Configuration::getInstance().memSpec->clk.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().NumberOfDevicesOnDIMM ) / ( 1024 ); + + std::cout << name() << string(" Total Time: ") + << sc_time_stamp().to_string() + << std::endl; + std::cout << name() << string(" AVG BW: ") + << std::fixed << std::setprecision(2) + << ((bandwidth / 100) * maxBandwidth) + << " Gibit/s (" << bandwidth << " %)" + << std::endl; + std::cout << name() << string(" AVG BW\\IDLE: ") + << std::fixed << std::setprecision(2) + << ((bandwidth_IDLE / 100) * maxBandwidth) + << " Gibit/s (" << bandwidth_IDLE << " %)" + << endl; + std::cout << name() << string(" MAX BW: ") + << std::fixed << std::setprecision(2) + << maxBandwidth << " Gibit/s" + << std::endl; + delete checker; for (auto it : bankMachines) delete it.second; @@ -203,6 +243,10 @@ void ControllerNew::releasePayload() payloadToRelease->release(); numberOfPayloads--; payloadToRelease = nullptr; + + numberOfTransactionsServed++; + if (numberOfPayloads == 0) + startBandwidthIdleCollector(); } void ControllerNew::acquirePayload() @@ -210,6 +254,9 @@ void ControllerNew::acquirePayload() uint64_t id = DramExtension::getPayloadID(payloadToAcquire); printDebugMessage("Payload " + std::to_string(id) + " entered system."); + if (numberOfPayloads == 0) + endBandwithIdleCollector(); + scheduler->storeRequest(payloadToAcquire); payloadToAcquire->acquire(); numberOfPayloads++; @@ -245,3 +292,23 @@ void ControllerNew::sendToDram(Command command, tlm_generic_payload *payload) iSocket->nb_transport_fw(*payload, phase, delay); } + +void ControllerNew::startBandwidthIdleCollector() +{ + if (!isIdle) + { + printDebugMessage("IDLE start"); + idleStart = sc_time_stamp(); + isIdle = true; + } +} + +void ControllerNew::endBandwithIdleCollector() +{ + if (isIdle) + { + printDebugMessage("IDLE end"); + idleTime += sc_time_stamp() - idleStart; + isIdle = false; + } +} diff --git a/DRAMSys/library/src/controller/ControllerNew.h b/DRAMSys/library/src/controller/ControllerNew.h index 75e61fee..71f9b532 100644 --- a/DRAMSys/library/src/controller/ControllerNew.h +++ b/DRAMSys/library/src/controller/ControllerNew.h @@ -98,6 +98,15 @@ private: void triggerEventQueueAfterDelay(sc_time); std::map commandFinishedTime; + + // Bandwidth related: + sc_time idleStart; + sc_time idleTime = SC_ZERO_TIME; + bool isIdle = false; + void startBandwidthIdleCollector(); + void endBandwithIdleCollector(); + + uint64_t numberOfTransactionsServed = 0; }; #endif // CONTROLLERNEW_H