Clean up public API (DRAMSys.h)

Remove DRAMSysRecordable.h/cpp as the functionality has been incorporated into
DRAMSys.h/cpp. The databaseRecording config is now completely handled by
DRAMSys itself without needing the user of the library to instanciate DRAMSys
or DRAMSysRecordable depending on this config.
This commit is contained in:
2024-01-16 12:25:54 +01:00
parent 5391b4351d
commit 59cf73fe9c
11 changed files with 110 additions and 272 deletions

View File

@@ -42,9 +42,6 @@
#include "DRAMSys/common/DebugManager.h"
#include "DRAMSys/common/utils.h"
#include "DRAMSys/config/McConfig.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/controller/Controller.h"
#include "DRAMSys/configuration/memspec/MemSpecDDR3.h"
#include "DRAMSys/configuration/memspec/MemSpecDDR4.h"
@@ -77,13 +74,6 @@ namespace DRAMSys
{
DRAMSys::DRAMSys(const sc_core::sc_module_name& name, const Config::Configuration& config) :
DRAMSys(name, config, true)
{
}
DRAMSys::DRAMSys(const sc_core::sc_module_name& name,
const Config::Configuration& config,
bool initAndBind) :
sc_module(name),
memSpec(createMemSpec(config.memspec)),
simConfig(config.simconfig),
@@ -98,9 +88,40 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name& name,
// Setup the debug manager:
setupDebugManager(simConfig.simulationName);
if (initAndBind)
// Instantiate all internal DRAMSys modules:
if (simConfig.databaseRecording)
{
std::string traceName = simConfig.simulationName;
if (!config.simulationid.empty())
traceName = config.simulationid + '_' + traceName;
// Create and properly initialize TLM recorders.
// They need to be ready before creating some modules.
setupTlmRecorders(traceName, config);
// Create controllers and DRAMs
for (std::size_t i = 0; i < memSpec->numberOfChannels; i++)
{
controllers.emplace_back(
std::make_unique<ControllerRecordable>(("controller" + std::to_string(i)).c_str(),
mcConfig,
simConfig,
*memSpec,
*addressDecoder,
tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable>(
("dram" + std::to_string(i)).c_str(), simConfig, *memSpec, tlmRecorders[i]));
if (simConfig.checkTLM2Protocol)
controllersTlmCheckers.emplace_back(
std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(
("TLMCheckerController" + std::to_string(i)).c_str()));
}
}
else
{
// Instantiate all internal DRAMSys modules:
for (std::size_t i = 0; i < memSpec->numberOfChannels; i++)
{
controllers.emplace_back(std::make_unique<Controller>(
@@ -110,14 +131,59 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name& name,
std::make_unique<Dram>(("dram" + std::to_string(i)).c_str(), simConfig, *memSpec));
if (simConfig.checkTLM2Protocol)
{
controllersTlmCheckers.push_back(
std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(
("TlmCheckerController" + std::to_string(i)).c_str()));
}
}
}
// Connect all internal DRAMSys modules:
bindSockets();
report();
// Connect all internal DRAMSys modules:
tSocket.bind(arbiter->tSocket);
for (unsigned i = 0; i < memSpec->numberOfChannels; i++)
{
if (simConfig.checkTLM2Protocol)
{
arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket);
controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket);
}
else
{
arbiter->iSocket.bind(controllers[i]->tSocket);
}
controllers[i]->iSocket.bind(drams[i]->tSocket);
}
report();
}
void DRAMSys::setupTlmRecorders(const std::string& traceName, const Config::Configuration& config)
{
// Create TLM Recorders, one per channel.
// Reserve is required because the recorders use double buffers that are accessed with pointers.
// Without a reserve, the vector reallocates storage before inserting a second
// element and the pointers are not valid anymore.
tlmRecorders.reserve(memSpec->numberOfChannels);
for (std::size_t i = 0; i < memSpec->numberOfChannels; i++)
{
std::string dbName =
std::string(name()) + "_" + traceName + "_ch" + std::to_string(i) + ".tdb";
std::string recorderName = "tlmRecorder" + std::to_string(i);
nlohmann::json mcconfig;
nlohmann::json memspec;
mcconfig[Config::McConfig::KEY] = config.mcconfig;
memspec[Config::MemSpec::KEY] = config.memspec;
tlmRecorders.emplace_back(recorderName,
simConfig,
mcConfig,
*memSpec,
dbName,
mcconfig.dump(),
memspec.dump(),
simConfig.simulationName);
}
}
@@ -143,6 +209,9 @@ void DRAMSys::end_of_simulation()
for (auto& dram : drams)
dram->reportPower();
}
for (auto& tlmRecorder : tlmRecorders)
tlmRecorder.finalize();
}
void DRAMSys::logo()
@@ -179,25 +248,6 @@ void DRAMSys::setupDebugManager([[maybe_unused]] const std::string& traceName) c
#endif
}
void DRAMSys::bindSockets()
{
tSocket.bind(arbiter->tSocket);
for (unsigned i = 0; i < memSpec->numberOfChannels; i++)
{
if (simConfig.checkTLM2Protocol)
{
arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket);
controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket);
}
else
{
arbiter->iSocket.bind(controllers[i]->tSocket);
}
controllers[i]->iSocket.bind(drams[i]->tSocket);
}
}
void DRAMSys::report()
{
PRINTDEBUGMESSAGE(name(), headline.data());

View File

@@ -41,16 +41,17 @@
#ifndef DRAMSYS_H
#define DRAMSYS_H
#include "DRAMSys/common/Serialize.h"
#include "DRAMSys/common/TlmRecorder.h"
#include "DRAMSys/common/tlm2_base_protocol_checker.h"
#include "DRAMSys/config/DRAMSysConfiguration.h"
#include "DRAMSys/config/SimConfig.h"
#include "DRAMSys/controller/Controller.h"
#include "DRAMSys/controller/ControllerRecordable.h"
#include "DRAMSys/controller/McConfig.h"
#include "DRAMSys/simulation/AddressDecoder.h"
#include "DRAMSys/simulation/Arbiter.h"
#include "DRAMSys/simulation/ReorderBuffer.h"
#include "DRAMSys/simulation/Dram.h"
#include "DRAMSys/simulation/DramRecordable.h"
#include "DRAMSys/simulation/SimConfig.h"
#include "DRAMSys/simulation/dram/Dram.h"
#include <list>
#include <memory>
@@ -87,13 +88,21 @@ public:
*/
void registerIdleCallback(const std::function<void()>& idleCallback);
protected:
DRAMSys(const sc_core::sc_module_name& name,
const Config::Configuration& config,
bool initAndBind);
private:
static void logo();
static std::unique_ptr<const MemSpec> createMemSpec(const Config::MemSpec& memSpec);
static std::unique_ptr<Arbiter> createArbiter(const SimConfig& simConfig,
const McConfig& mcConfig,
const MemSpec& memSpec,
const AddressDecoder& addressDecoder);
void end_of_simulation() override;
void setupDebugManager(const std::string& traceName) const;
void setupTlmRecorders(const std::string& traceName, const Config::Configuration& configLib);
void report();
std::unique_ptr<const MemSpec> memSpec;
SimConfig simConfig;
McConfig mcConfig;
@@ -103,9 +112,6 @@ protected:
// TLM 2.0 Protocol Checkers
std::vector<std::unique_ptr<tlm_utils::tlm2_base_protocol_checker<>>> controllersTlmCheckers;
// TODO: Each DRAM has a reorder buffer (check this!)
std::unique_ptr<ReorderBuffer> reorder;
// All transactions pass through the same arbiter
std::unique_ptr<Arbiter> arbiter;
@@ -115,20 +121,9 @@ protected:
// DRAM units
std::vector<std::unique_ptr<Dram>> drams;
void report();
void bindSockets();
private:
static void logo();
static std::unique_ptr<const MemSpec> createMemSpec(const Config::MemSpec& memSpec);
static std::unique_ptr<Arbiter> createArbiter(const SimConfig& simConfig,
const McConfig& mcConfig,
const MemSpec& memSpec,
const AddressDecoder& addressDecoder);
void setupDebugManager(const std::string& traceName) const;
static constexpr Config::ArbiterType DEFAULT_ARBITER = Config::ArbiterType::Simple;
// Transaction Recorders (one per channel).
// They generate the output databases.
std::vector<TlmRecorder> tlmRecorders;
};
} // namespace DRAMSys

View File

@@ -1,134 +0,0 @@
/*
* Copyright (c) 2020, 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:
* Lukas Steiner
* Derek Christ
*/
#include "DRAMSysRecordable.h"
#include "DRAMSys/common/TlmRecorder.h"
#include "DRAMSys/controller/ControllerRecordable.h"
#include "DRAMSys/simulation/dram/DramRecordable.h"
#include <memory>
namespace DRAMSys
{
DRAMSysRecordable::DRAMSysRecordable(const sc_core::sc_module_name& name,
const Config::Configuration& config) :
DRAMSys(name, config, false)
{
// If a simulation file is passed as argument to DRAMSys the simulation ID
// is prepended to the simulation name if found.
std::string traceName;
if (!config.simulationid.empty())
{
std::string sid = config.simulationid;
traceName = sid + '_' + simConfig.simulationName;
}
else
traceName = simConfig.simulationName;
// Create and properly initialize TLM recorders.
// They need to be ready before creating some modules.
setupTlmRecorders(traceName, config);
// Create controllers and DRAMs
for (std::size_t i = 0; i < memSpec->numberOfChannels; i++)
{
controllers.emplace_back(
std::make_unique<ControllerRecordable>(("controller" + std::to_string(i)).c_str(),
mcConfig,
simConfig,
*memSpec,
*addressDecoder,
tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable>(
("dram" + std::to_string(i)).c_str(), simConfig, *memSpec, tlmRecorders[i]));
if (simConfig.checkTLM2Protocol)
controllersTlmCheckers.emplace_back(
std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(
("TLMCheckerController" + std::to_string(i)).c_str()));
}
bindSockets();
report();
}
void DRAMSysRecordable::end_of_simulation()
{
// Report power before TLM recorders are finalized
if (simConfig.powerAnalysis)
{
for (auto& dram : drams)
dram->reportPower();
}
for (auto& tlmRecorder : tlmRecorders)
tlmRecorder.finalize();
}
void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName,
const Config::Configuration& config)
{
// Create TLM Recorders, one per channel.
// Reserve is required because the recorders use double buffers that are accessed with pointers.
// Without a reserve, the vector reallocates storage before inserting a second
// element and the pointers are not valid anymore.
tlmRecorders.reserve(memSpec->numberOfChannels);
for (std::size_t i = 0; i < memSpec->numberOfChannels; i++)
{
std::string dbName =
std::string(name()) + "_" + traceName + "_ch" + std::to_string(i) + ".tdb";
std::string recorderName = "tlmRecorder" + std::to_string(i);
nlohmann::json mcconfig;
nlohmann::json memspec;
mcconfig[Config::McConfig::KEY] = config.mcconfig;
memspec[Config::MemSpec::KEY] = config.memspec;
tlmRecorders.emplace_back(recorderName,
simConfig,
mcConfig,*memSpec,
dbName,
mcconfig.dump(),
memspec.dump(),
simConfig.simulationName);
}
}
} // namespace DRAMSys

View File

@@ -1,67 +0,0 @@
/*
* Copyright (c) 2020, 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:
* Lukas Steiner
* Derek Christ
*/
#ifndef DRAMSYSRECORDABLE_H
#define DRAMSYSRECORDABLE_H
#include "DRAMSys/common/TlmRecorder.h"
#include "DRAMSys/config/DRAMSysConfiguration.h"
#include "DRAMSys/simulation/DRAMSys.h"
namespace DRAMSys
{
class DRAMSysRecordable : public DRAMSys
{
public:
DRAMSysRecordable(const sc_core::sc_module_name& name,
const Config::Configuration& configLib);
protected:
void end_of_simulation() override;
private:
// Transaction Recorders (one per channel).
// They generate the output databases.
std::vector<TlmRecorder> tlmRecorders;
void setupTlmRecorders(const std::string& traceName,
const Config::Configuration& configLib);
};
} // namespace DRAMSys
#endif // DRAMSYSRECORDABLE_H

View File

@@ -46,17 +46,9 @@ Simulator::Simulator(DRAMSys::Config::Configuration configuration,
storageEnabled(configuration.simconfig.StoreMode == DRAMSys::Config::StoreModeType::Store),
memoryManager(storageEnabled),
configuration(std::move(configuration)),
resourceDirectory(std::move(resourceDirectory))
resourceDirectory(std::move(resourceDirectory)),
dramSys(std::make_unique<DRAMSys::DRAMSys>("DRAMSys", this->configuration))
{
if (this->configuration.simconfig.DatabaseRecording.value_or(false))
{
dramSys = std::make_unique<DRAMSys::DRAMSysRecordable>("DRAMSys", this->configuration);
}
else
{
dramSys = std::make_unique<DRAMSys::DRAMSys>("DRAMSys", this->configuration);
}
terminateInitiator = [this]()
{
terminatedInitiators++;
@@ -74,7 +66,10 @@ Simulator::Simulator(DRAMSys::Config::Configuration configuration,
};
if (!configuration.tracesetup.has_value())
{
SC_REPORT_FATAL("Simulator", "No traffic initiators specified");
std::abort(); // Silence warning
}
for (const auto& initiatorConfig : *this->configuration.tracesetup)
{

View File

@@ -39,7 +39,7 @@
#include "MemoryManager.h"
#include <DRAMSys/config/DRAMSysConfiguration.h>
#include <DRAMSys/simulation/DRAMSysRecordable.h>
#include <DRAMSys/simulation/DRAMSys.h>
static constexpr std::string_view TRACE_DIRECTORY = "traces";

View File

@@ -36,7 +36,6 @@
#include <gtest/gtest.h>
#include <DRAMSys/simulation/DRAMSys.h>
#include <DRAMSys/simulation/dram/Dram.h>
class SystemCTest : public testing::Test
{