233 lines
9.2 KiB
C++
233 lines
9.2 KiB
C++
/*
|
|
* Copyright (c) 2015, Technische Universität Kaiserslautern
|
|
* 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:
|
|
* Janik Schlemminger
|
|
* Matthias Jung
|
|
* Eder F. Zulian
|
|
* Felipe S. Prado
|
|
* Lukas Steiner
|
|
*/
|
|
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <stdexcept>
|
|
|
|
#include "DRAMSys.h"
|
|
#include "../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
|
#include "../common/DebugManager.h"
|
|
#include "../common/utils.h"
|
|
#include "../simulation/TemperatureController.h"
|
|
#include "../error/ecchamming.h"
|
|
#include "dram/DramDDR3.h"
|
|
#include "dram/DramDDR4.h"
|
|
#include "dram/DramDDR5.h"
|
|
#include "dram/DramWideIO.h"
|
|
#include "dram/DramLPDDR4.h"
|
|
#include "dram/DramLPDDR5.h"
|
|
#include "dram/DramWideIO2.h"
|
|
#include "dram/DramHBM2.h"
|
|
#include "dram/DramGDDR5.h"
|
|
#include "dram/DramGDDR5X.h"
|
|
#include "dram/DramGDDR6.h"
|
|
#include "dram/DramSTTMRAM.h"
|
|
#include "../controller/Controller.h"
|
|
|
|
DRAMSys::DRAMSys(const sc_core::sc_module_name &name,
|
|
const std::string &simulationToRun,
|
|
const std::string &pathToResources)
|
|
: DRAMSys(name, simulationToRun, pathToResources, true)
|
|
{}
|
|
|
|
DRAMSys::DRAMSys(const sc_core::sc_module_name &name,
|
|
const std::string &simulationToRun,
|
|
const std::string &pathToResources,
|
|
bool initAndBind)
|
|
: sc_module(name), tSocket("DRAMSys_tSocket")
|
|
{
|
|
logo();
|
|
|
|
// Read Configuration Setup:
|
|
nlohmann::json simulationdoc = parseJSON(simulationToRun);
|
|
|
|
Configuration::getInstance().setPathToResources(pathToResources);
|
|
|
|
// Load config and initialize modules
|
|
Configuration::getInstance().loadMemSpec(Configuration::getInstance(),
|
|
pathToResources
|
|
+ "configs/memspecs/"
|
|
+ std::string(simulationdoc["simulation"]["memspec"]));
|
|
|
|
Configuration::loadMCConfig(Configuration::getInstance(),
|
|
pathToResources
|
|
+ "configs/mcconfigs/"
|
|
+ std::string(simulationdoc["simulation"]["mcconfig"]));
|
|
|
|
Configuration::loadSimConfig(Configuration::getInstance(),
|
|
pathToResources
|
|
+ "configs/simulator/"
|
|
+ std::string(simulationdoc["simulation"]["simconfig"]));
|
|
|
|
Configuration::loadTemperatureSimConfig(Configuration::getInstance(),
|
|
pathToResources
|
|
+ "configs/thermalsim/"
|
|
+ std::string(simulationdoc["simulation"]["thermalconfig"]));
|
|
|
|
// Setup the debug manager:
|
|
setupDebugManager(Configuration::getInstance().simulationName);
|
|
|
|
if (initAndBind)
|
|
{
|
|
// Instantiate all internal DRAMSys modules:
|
|
std::string amconfig = simulationdoc["simulation"]["addressmapping"];
|
|
instantiateModules(pathToResources, amconfig);
|
|
// Connect all internal DRAMSys modules:
|
|
bindSockets();
|
|
report(headline);
|
|
}
|
|
}
|
|
|
|
void DRAMSys::logo()
|
|
{
|
|
#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;
|
|
#undef GREENTXT
|
|
#undef DGREENTXT
|
|
#undef LGREENTXT
|
|
#undef BLACKTXT
|
|
#undef BOLDTXT
|
|
}
|
|
|
|
void DRAMSys::setupDebugManager(NDEBUG_UNUSED(const std::string &traceName))
|
|
{
|
|
#ifndef NDEBUG
|
|
auto &dbg = DebugManager::getInstance();
|
|
dbg.writeToConsole = false;
|
|
dbg.writeToFile = true;
|
|
if (dbg.writeToFile)
|
|
dbg.openDebugFile(traceName + ".txt");
|
|
#endif
|
|
}
|
|
|
|
void DRAMSys::instantiateModules(const std::string &pathToResources,
|
|
const std::string &amconfig)
|
|
{
|
|
// The first call to getInstance() creates the Temperature Controller.
|
|
// The same instance will be accessed by all other modules.
|
|
TemperatureController::getInstance();
|
|
Configuration &config = Configuration::getInstance();
|
|
|
|
// Create arbiter
|
|
if (config.arbiter == Configuration::Arbiter::Simple)
|
|
arbiter = std::unique_ptr<Arbiter>(new ArbiterSimple("arbiter", pathToResources + "configs/amconfigs/" + amconfig));
|
|
else if (config.arbiter == Configuration::Arbiter::Fifo)
|
|
arbiter = std::unique_ptr<Arbiter>(new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig));
|
|
else if (config.arbiter == Configuration::Arbiter::Reorder)
|
|
arbiter = std::unique_ptr<Arbiter>(new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig));
|
|
|
|
// Create controllers and DRAMs
|
|
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
|
|
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
|
|
{
|
|
controllers.emplace_back(new Controller(("controller" + std::to_string(i)).c_str()));
|
|
|
|
if (memoryType == MemSpec::MemoryType::DDR3)
|
|
drams.emplace_back(new DramDDR3(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::DDR4)
|
|
drams.emplace_back(new DramDDR4(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::DDR5)
|
|
drams.emplace_back(new DramDDR5(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::WideIO)
|
|
drams.emplace_back(new DramWideIO(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::LPDDR4)
|
|
drams.emplace_back(new DramLPDDR4(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::LPDDR5)
|
|
drams.emplace_back(new DramLPDDR5(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::WideIO2)
|
|
drams.emplace_back(new DramWideIO2(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::HBM2)
|
|
drams.emplace_back(new DramHBM2(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::GDDR5)
|
|
drams.emplace_back(new DramGDDR5(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::GDDR5X)
|
|
drams.emplace_back(new DramGDDR5X(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::GDDR6)
|
|
drams.emplace_back(new DramGDDR6(("dram" + std::to_string(i)).c_str()));
|
|
else if (memoryType == MemSpec::MemoryType::STTMRAM)
|
|
drams.emplace_back(new DramSTTMRAM(("dram" + std::to_string(i)).c_str()));
|
|
|
|
if (config.checkTLM2Protocol)
|
|
controllersTlmCheckers.push_back(new tlm_utils::tlm2_base_protocol_checker<>(("TlmCheckerController" + std::to_string(i)).c_str()));
|
|
}
|
|
}
|
|
|
|
void DRAMSys::bindSockets()
|
|
{
|
|
Configuration &config = Configuration::getInstance();
|
|
|
|
tSocket.bind(arbiter->tSocket);
|
|
|
|
for (unsigned i = 0; i < config.memSpec->numberOfChannels; i++)
|
|
{
|
|
if (config.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(const std::string &message)
|
|
{
|
|
PRINTDEBUGMESSAGE(name(), message);
|
|
std::cout << message << std::endl;
|
|
}
|