Remove ControllerIF.h

It provided no advantage and made things unecessary complicated
This commit is contained in:
2024-01-11 09:28:58 +01:00
parent 5eabecc9f9
commit d92ea325c3
7 changed files with 108 additions and 188 deletions

View File

@@ -81,8 +81,9 @@ namespace DRAMSys
Controller::Controller(const sc_module_name& name,
const Configuration& config,
const MemSpec& memSpec,
const AddressDecoder& addressDecoder) :
ControllerIF(name, config),
memSpec(memSpec),
thinkDelayFw(config.thinkDelayFw),
thinkDelayBw(config.thinkDelayBw),
phyDelayFw(config.phyDelayFw),
@@ -96,6 +97,13 @@ Controller::Controller(const sc_module_name& name,
SC_METHOD(controllerMethod);
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw);
tSocket.register_transport_dbg(this, &Controller::transport_dbg);
tSocket.register_b_transport(this, &Controller::b_transport);
iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw);
idleTimeCollector.start();
ranksNumberOfPayloads = ControllerVector<Rank, unsigned>(memSpec.ranksPerChannel);
// reserve buffer for command tuples
@@ -273,11 +281,6 @@ Controller::Controller(const sc_module_name& name,
SC_REPORT_FATAL("Controller", "Selected refresh mode not supported!");
}
bool Controller::idle() const
{
return totalNumberOfPayloads == 0;
}
void Controller::registerIdleCallback(std::function<void()> idleCallback)
{
this->idleCallback = std::move(idleCallback);
@@ -736,4 +739,42 @@ void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans)
ParentExtension::setExtension(parentTrans, std::move(childTranses));
}
void Controller::end_of_simulation()
{
idleTimeCollector.end();
sc_core::sc_time activeTime = static_cast<double>(numberOfBeatsServed) / memSpec.dataRate *
memSpec.tCK / memSpec.pseudoChannelsPerChannel;
double bandwidth = activeTime / sc_core::sc_time_stamp();
double bandwidthWoIdle =
activeTime / (sc_core::sc_time_stamp() - idleTimeCollector.getIdleTime());
double maxBandwidth = (
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
(1000 / memSpec.tCK.to_double())
// DataRate e.g. 2
* memSpec.dataRate
// BusWidth e.g. 8 or 64
* memSpec.bitWidth
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
* memSpec.devicesPerRank
// HBM specific, one or two pseudo channels per channel
* memSpec.pseudoChannelsPerChannel);
std::cout << name() << std::string(" Total Time: ") << sc_core::sc_time_stamp().to_string()
<< std::endl;
std::cout << name() << std::string(" AVG BW: ") << std::fixed << std::setprecision(2)
<< std::setw(6) << (bandwidth * maxBandwidth) << " Gb/s | " << std::setw(6)
<< (bandwidth * maxBandwidth / 8) << " GB/s | " << std::setw(6) << (bandwidth * 100)
<< " %" << std::endl;
std::cout << name() << std::string(" AVG BW\\IDLE: ") << std::fixed << std::setprecision(2)
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth) << " Gb/s | " << std::setw(6)
<< (bandwidthWoIdle * maxBandwidth / 8) << " GB/s | " << std::setw(6)
<< (bandwidthWoIdle * 100) << " %" << std::endl;
std::cout << name() << std::string(" MAX BW: ") << std::fixed << std::setprecision(2)
<< std::setw(6) << maxBandwidth << " Gb/s | " << std::setw(6) << maxBandwidth / 8
<< " GB/s | " << std::setw(6) << 100.0 << " %" << std::endl;
}
} // namespace DRAMSys

View File

@@ -35,9 +35,9 @@
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include "DRAMSys/common/DebugManager.h"
#include "DRAMSys/controller/BankMachine.h"
#include "DRAMSys/controller/Command.h"
#include "DRAMSys/controller/ControllerIF.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/controller/cmdmux/CmdMuxIF.h"
#include "DRAMSys/controller/powerdown/PowerDownManagerIF.h"
@@ -45,41 +45,51 @@
#include "DRAMSys/controller/respqueue/RespQueueIF.h"
#include "DRAMSys/simulation/AddressDecoder.h"
#include <functional>
#include <stack>
#include <systemc>
#include <tlm>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include <utility>
#include <vector>
namespace DRAMSys
{
class Controller : public ControllerIF
class Controller : public sc_core::sc_module
{
public:
tlm_utils::simple_target_socket<Controller> tSocket{"tSocket"}; // Arbiter side
tlm_utils::simple_initiator_socket<Controller> iSocket{"iSocket"}; // DRAM side
Controller(const sc_core::sc_module_name& name,
const Configuration& config,
const MemSpec& memSpec,
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(Controller);
[[nodiscard]] bool idle() const override;
[[nodiscard]] bool idle() const { return totalNumberOfPayloads == 0; }
void registerIdleCallback(std::function<void()> idleCallback);
protected:
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
void end_of_simulation() override;
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) override;
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
sc_core::sc_time& delay);
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) override;
void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) override;
unsigned int transport_dbg(tlm::tlm_generic_payload& trans) override;
sc_core::sc_time& delay);
void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
virtual void
sendToFrontend(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay);
virtual void controllerMethod();
const MemSpec& memSpec;
std::unique_ptr<SchedulerIF> scheduler;
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
@@ -90,7 +100,7 @@ protected:
const sc_core::sc_time blockingReadDelay;
const sc_core::sc_time blockingWriteDelay;
private:
uint64_t numberOfBeatsServed = 0;
unsigned totalNumberOfPayloads = 0;
std::function<void()> idleCallback;
ControllerVector<Rank, unsigned> ranksNumberOfPayloads;
@@ -139,6 +149,37 @@ private:
private:
std::stack<tlm::tlm_generic_payload*> freePayloads;
} memoryManager;
class IdleTimeCollector
{
public:
void start()
{
if (!isIdle)
{
PRINTDEBUGMESSAGE("IdleTimeCollector", "IDLE start");
idleStart = sc_core::sc_time_stamp();
isIdle = true;
}
}
void end()
{
if (isIdle)
{
PRINTDEBUGMESSAGE("IdleTimeCollector", "IDLE end");
idleTime += sc_core::sc_time_stamp() - idleStart;
isIdle = false;
}
}
sc_core::sc_time getIdleTime() { return idleTime; }
private:
bool isIdle = false;
sc_core::sc_time idleTime = sc_core::SC_ZERO_TIME;
sc_core::sc_time idleStart;
} idleTimeCollector;
};
} // namespace DRAMSys

View File

@@ -1,168 +0,0 @@
/*
* Copyright (c) 2019, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Kirill Bykov
* Lukas Steiner
*/
#ifndef CONTROLLERIF_H
#define CONTROLLERIF_H
#include "DRAMSys/common/DebugManager.h"
#include "DRAMSys/configuration/Configuration.h"
#include <iomanip>
#include <systemc>
#include <tlm>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
namespace DRAMSys
{
// Utility class to pass around DRAMSys, without having to propagate the template definitions
// throughout all classes
class ControllerIF : public sc_core::sc_module
{
public:
// Already create and bind sockets to the virtual functions
tlm_utils::simple_target_socket<ControllerIF> tSocket; // Arbiter side
tlm_utils::simple_initiator_socket<ControllerIF> iSocket; // DRAM side
void end_of_simulation() override
{
idleTimeCollector.end();
sc_core::sc_time activeTime = static_cast<double>(numberOfBeatsServed) / memSpec.dataRate *
memSpec.tCK / memSpec.pseudoChannelsPerChannel;
double bandwidth = activeTime / sc_core::sc_time_stamp();
double bandwidthWoIdle =
activeTime / (sc_core::sc_time_stamp() - idleTimeCollector.getIdleTime());
double maxBandwidth = (
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
(1000 / memSpec.tCK.to_double())
// DataRate e.g. 2
* memSpec.dataRate
// BusWidth e.g. 8 or 64
* memSpec.bitWidth
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
* memSpec.devicesPerRank
// HBM specific, one or two pseudo channels per channel
* memSpec.pseudoChannelsPerChannel);
std::cout << name() << std::string(" Total Time: ")
<< sc_core::sc_time_stamp().to_string() << std::endl;
std::cout << name() << std::string(" AVG BW: ") << std::fixed
<< std::setprecision(2) << std::setw(6) << (bandwidth * maxBandwidth)
<< " Gb/s | " << std::setw(6) << (bandwidth * maxBandwidth / 8) << " GB/s | "
<< std::setw(6) << (bandwidth * 100) << " %" << std::endl;
std::cout << name() << std::string(" AVG BW\\IDLE: ") << std::fixed
<< std::setprecision(2) << std::setw(6) << (bandwidthWoIdle * maxBandwidth)
<< " Gb/s | " << std::setw(6) << (bandwidthWoIdle * maxBandwidth / 8)
<< " GB/s | " << std::setw(6) << (bandwidthWoIdle * 100) << " %" << std::endl;
std::cout << name() << std::string(" MAX BW: ") << std::fixed
<< std::setprecision(2) << std::setw(6) << maxBandwidth << " Gb/s | "
<< std::setw(6) << maxBandwidth / 8 << " GB/s | " << std::setw(6) << 100.0 << " %"
<< std::endl;
}
[[nodiscard]] virtual bool idle() const = 0;
protected:
const MemSpec& memSpec;
// Bind sockets with virtual functions
ControllerIF(const sc_core::sc_module_name& name, const Configuration& config) :
sc_core::sc_module(name),
tSocket("tSocket"),
iSocket("iSocket"),
memSpec(*config.memSpec)
{
tSocket.register_nb_transport_fw(this, &ControllerIF::nb_transport_fw);
tSocket.register_transport_dbg(this, &ControllerIF::transport_dbg);
tSocket.register_b_transport(this, &ControllerIF::b_transport);
iSocket.register_nb_transport_bw(this, &ControllerIF::nb_transport_bw);
idleTimeCollector.start();
}
SC_HAS_PROCESS(ControllerIF);
// Virtual transport functions
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) = 0;
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) = 0;
virtual void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) = 0;
virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans) = 0;
// Bandwidth related
class IdleTimeCollector
{
public:
void start()
{
if (!isIdle)
{
PRINTDEBUGMESSAGE("IdleTimeCollector", "IDLE start");
idleStart = sc_core::sc_time_stamp();
isIdle = true;
}
}
void end()
{
if (isIdle)
{
PRINTDEBUGMESSAGE("IdleTimeCollector", "IDLE end");
idleTime += sc_core::sc_time_stamp() - idleStart;
isIdle = false;
}
}
sc_core::sc_time getIdleTime() { return idleTime; }
private:
bool isIdle = false;
sc_core::sc_time idleTime = sc_core::SC_ZERO_TIME;
sc_core::sc_time idleStart;
} idleTimeCollector;
uint64_t numberOfBeatsServed = 0;
};
} // namespace DRAMSys
#endif // CONTROLLERIF_H

View File

@@ -44,9 +44,10 @@ namespace DRAMSys
ControllerRecordable::ControllerRecordable(const sc_module_name& name,
const Configuration& config,
const MemSpec& memSpec,
const AddressDecoder& addressDecoder,
TlmRecorder& tlmRecorder) :
Controller(name, config, addressDecoder),
Controller(name, config, memSpec, addressDecoder),
tlmRecorder(tlmRecorder),
windowSizeTime(config.windowSize * memSpec.tCK),
activeTimeMultiplier(config.memSpec->tCK / config.memSpec->dataRate),

View File

@@ -49,6 +49,7 @@ class ControllerRecordable final : public Controller
public:
ControllerRecordable(const sc_core::sc_module_name& name,
const Configuration& config,
const MemSpec& memSpec,
const AddressDecoder& addressDecoder,
TlmRecorder& tlmRecorder);

View File

@@ -167,7 +167,7 @@ void DRAMSys::instantiateModules(const ::DRAMSys::Config::AddressMapping& addres
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
{
controllers.emplace_back(std::make_unique<Controller>(
("controller" + std::to_string(i)).c_str(), config, *addressDecoder));
("controller" + std::to_string(i)).c_str(), config, *config.memSpec, *addressDecoder));
drams.emplace_back(std::make_unique<Dram>(("dram" + std::to_string(i)).c_str(), config));

View File

@@ -125,8 +125,12 @@ void DRAMSysRecordable::instantiateModules(const std::string& traceName,
// Create controllers and DRAMs
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
{
controllers.emplace_back(std::make_unique<ControllerRecordable>(
("controller" + std::to_string(i)).c_str(), config, *addressDecoder, tlmRecorders[i]));
controllers.emplace_back(
std::make_unique<ControllerRecordable>(("controller" + std::to_string(i)).c_str(),
config,
*config.memSpec,
*addressDecoder,
tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));