From 6f0e2a00e19435520c47962f1c15fc005ac652c7 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Wed, 8 Feb 2017 17:00:31 +0100 Subject: [PATCH 01/19] Added several files with test software for ECC Codes. --- DRAMSys/simulator/src/error/ECC/Bit.cpp | 25 ++++ DRAMSys/simulator/src/error/ECC/Bit.h | 66 ++++++++++ DRAMSys/simulator/src/error/ECC/ECC.cpp | 91 +++++++++++++ DRAMSys/simulator/src/error/ECC/ECC.h | 21 +++ DRAMSys/simulator/src/error/ECC/ECC_Test.cpp | 128 +++++++++++++++++++ DRAMSys/simulator/src/error/ECC/Word.cpp | 117 +++++++++++++++++ DRAMSys/simulator/src/error/ECC/Word.h | 60 +++++++++ 7 files changed, 508 insertions(+) create mode 100644 DRAMSys/simulator/src/error/ECC/Bit.cpp create mode 100644 DRAMSys/simulator/src/error/ECC/Bit.h create mode 100644 DRAMSys/simulator/src/error/ECC/ECC.cpp create mode 100644 DRAMSys/simulator/src/error/ECC/ECC.h create mode 100644 DRAMSys/simulator/src/error/ECC/ECC_Test.cpp create mode 100644 DRAMSys/simulator/src/error/ECC/Word.cpp create mode 100644 DRAMSys/simulator/src/error/ECC/Word.h diff --git a/DRAMSys/simulator/src/error/ECC/Bit.cpp b/DRAMSys/simulator/src/error/ECC/Bit.cpp new file mode 100644 index 00000000..b5faee9a --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/Bit.cpp @@ -0,0 +1,25 @@ +#include "stdafx.h" +#include "Bit.h" + + +CBit::CBit(VALUE nVal) +{ + m_nValue = nVal; +} + + +CBit::~CBit() +{ +} + +void CBit::Print() +{ + if (m_nValue == ZERO) + { + printf("0"); + } + else + { + printf("1"); + } +} diff --git a/DRAMSys/simulator/src/error/ECC/Bit.h b/DRAMSys/simulator/src/error/ECC/Bit.h new file mode 100644 index 00000000..74aec5da --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/Bit.h @@ -0,0 +1,66 @@ +#pragma once +class CBit +{ +public: + enum VALUE + { + ZERO = 0, + ONE = 1 + }; + +protected: + VALUE m_nValue; + +public: + CBit(VALUE nVal = ZERO); + virtual ~CBit(); + + inline void Set() { m_nValue = ONE; }; + inline void Clear() { m_nValue = ZERO; }; + + void Print(); + + CBit& operator=(DWORD d) + { + if (d == 0 ) + { + m_nValue = ZERO; + } + else + { + m_nValue = ONE; + } + return *this; + } + + friend CBit operator^(CBit l, const CBit& r) + { + if (l.m_nValue == r.m_nValue) + { + return CBit(ZERO); + } + else + { + return CBit(ONE); + } + } + + CBit& operator^=(const CBit& r) + { + if (m_nValue == r.m_nValue) + { + m_nValue = ZERO; + } + else + { + m_nValue = ONE; + } + return *this; + } + + inline bool operator==(const CBit::VALUE& r) + { + return m_nValue == r; + } +}; + diff --git a/DRAMSys/simulator/src/error/ECC/ECC.cpp b/DRAMSys/simulator/src/error/ECC/ECC.cpp new file mode 100644 index 00000000..bbd230ba --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/ECC.cpp @@ -0,0 +1,91 @@ +#include "stdafx.h" + +#include "ECC.h" + +unsigned ECC::GetNumParityBits(unsigned nDataBits) +{ + unsigned nParityBits = 0; + + // n = 2^k - k - 1 + while (nDataBits > ((1 << nParityBits) - nParityBits - 1)) + { + ++nParityBits; + } + + return nParityBits+1; // +1 for SEC-DED +} + +void ECC::ExtendWord(CWord & v) +{ + unsigned end = v.GetLength() + ECC::GetNumParityBits(v.GetLength()); + + unsigned i = 1; + while (i < end) + { + v.Insert(i-1, CBit()); + i <<= 1; + } + + v.Append(CBit()); +} + +void ECC::CalculateCheckbits(CWord & v, CWord & p) +{ + // Hamming-Code Prüfbits füllen + unsigned i = 1, l = 0; + while (i < v.GetLength()) + { + for (unsigned j = (i - 1); j < v.GetLength(); j += (i << 1)) + { + for (unsigned k = 0; k < (i); k++) + { + p[l] ^= v[j + k]; + } + } + l++; + i <<= 1; + } +} + +void ECC::InsertCheckbits(CWord& v, CWord p) +{ + // Prüfbits einfügen + unsigned i = 1, j = 0; + while (i <= v.GetLength()) + { + v[i - 1] = p[j++]; + i <<= 1; + } + +} + +void ECC::ExtractCheckbits(CWord v, CWord & p) +{ + // Prüfbits extrahieren + unsigned i = 1, j = 0; + while(i <= v.GetLength()) + { + p[j++] = v[i - 1]; + i <<= 1; + } +} + +void ECC::CalculateParityBit(CWord v, CBit & p) +{ + // Paritybit + p = CBit::ZERO; + for (unsigned i = 0; i < v.GetLength(); i++) + { + p ^= v[i]; + } +} + +void ECC::InsertParityBit(CWord& v, CBit p) +{ + v[v.GetLength() - 1] = p; +} + +void ECC::ExtractParityBit(CWord v, CBit & p) +{ + p = v[v.GetLength() - 1]; +} diff --git a/DRAMSys/simulator/src/error/ECC/ECC.h b/DRAMSys/simulator/src/error/ECC/ECC.h new file mode 100644 index 00000000..8379999a --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/ECC.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Word.h" +#include "Bit.h" + +namespace ECC +{ + + unsigned GetNumParityBits(unsigned nDataBits); + + // Erweitert das Wort um zusätzliche Bits für die Berechnung des Hamming-Codes + void ExtendWord(CWord &v); + + void CalculateCheckbits(CWord &v, CWord & p); + void InsertCheckbits(CWord& v, CWord p); + void ExtractCheckbits(CWord v, CWord& p); + + void CalculateParityBit(CWord v, CBit& p); + void InsertParityBit(CWord& v, CBit p); + void ExtractParityBit(CWord v, CBit& p); +} diff --git a/DRAMSys/simulator/src/error/ECC/ECC_Test.cpp b/DRAMSys/simulator/src/error/ECC/ECC_Test.cpp new file mode 100644 index 00000000..dcbd884e --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/ECC_Test.cpp @@ -0,0 +1,128 @@ +// ECC_Test.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. +// + +#include "stdafx.h" +#include +#include "ECC.h" + +int main() +{ + // Random number init + srand(time(NULL)); + + // Erstellen + unsigned size = 4; + CWord p(ECC::GetNumParityBits(size)), v(size); + + // Daten eingeben + for (unsigned a = 0; a < 16; a++) + { + v = a; + v.Rotate(); + + ECC::ExtendWord(v); + printf("%d:\t", a); + + p = 0; + ECC::CalculateCheckbits(v, p); + ECC::InsertCheckbits(v, p); + ECC::CalculateParityBit(v, p[3]); + ECC::InsertParityBit(v, p[3]); + + v.Print(); + + v.Resize(size); + } + + printf("\r\n"); + + for (unsigned x = 0; x < 100; x++) + { + //Get random number + unsigned a = rand() % 16; + + v.Resize(size); + v = a; + v.Rotate(); + + ECC::ExtendWord(v); + + p = 0; + ECC::CalculateCheckbits(v, p); + ECC::InsertCheckbits(v, p); + ECC::CalculateParityBit(v, p[3]); + ECC::InsertParityBit(v, p[3]); + v.Print(); + + // Insert error + unsigned pos = rand() % 8; + v[pos] ^= CBit(CBit::ONE); + + printf("Data: %d, Error at pos %d: ", a, pos + 1); + v[pos].Print(); + printf("\r\n"); + v.Print(); + + p = 0; + ECC::CalculateCheckbits(v, p); + ECC::CalculateParityBit(v, p[3]); + + printf("%d:\t", a); + + p.Print(); + + // Interpreting Data + + unsigned syndrome = 0; + for (unsigned i = 0; i < p.GetLength() - 1; i++) + { + if (p[i] == CBit::ONE) + syndrome += (1 << i); + } + + if (p[3] == CBit::ZERO) + { + // Parity even + + if (syndrome) + { + // Double error + printf("Double error detected.\r\n"); + break; + } + else + { + // No Error + printf("No error detected.\r\n"); + break; + } + } + else + { + // Parity odd + + if (syndrome) + { + // Bit error + printf("Error detected in Bit %d.\r\n", syndrome); + if (syndrome == pos + 1) + continue; + else + break; + } + else + { + // Overall parity Error + printf("Overall parity error detected.\r\n"); + if (pos == 7 || pos == 3 || pos == 1 || pos == 0) + continue; + else + break; + } + } + } + system("pause"); + + return 0; +} + diff --git a/DRAMSys/simulator/src/error/ECC/Word.cpp b/DRAMSys/simulator/src/error/ECC/Word.cpp new file mode 100644 index 00000000..a94bdad7 --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/Word.cpp @@ -0,0 +1,117 @@ +#include "stdafx.h" +#include "Word.h" + + +CWord::CWord(unsigned nBitLength) + : m_nBitLength(nBitLength) +{ + m_word.resize(nBitLength); +} + + +CWord::~CWord() +{ +} + +CBit * CWord::GetAt(unsigned nBitPos) +{ + if (nBitPos < m_nBitLength) + { + return &m_word.at(nBitPos); + } + + return nullptr; +} + +void CWord::Set(DWORD data) +{ + deque::iterator it; + if (m_nBitLength < sizeof(data)) + { + it = m_word.begin(); + for (unsigned i = 0; i < m_nBitLength; i++) + { + (*it++) = data & 1; + data >>= 1; + } + } + else + { + for (it = m_word.begin(); it != m_word.end(); it++) + { + (*it) = data & 1; + data >>= 1; + } + } +} + +void CWord::Rotate() +{ + deque buffer = m_word; + for (unsigned i = 0; i < m_nBitLength; i++) + { + m_word.at(m_nBitLength -i -1) = buffer.at(i); + } +} + +bool CWord::Insert(unsigned npos, CBit b) +{ + if (npos >= m_nBitLength) + return false; + + deque::iterator it = m_word.begin() + npos; + m_word.insert(it, b); + + m_nBitLength++; + + return true; +} + +bool CWord::Delete(unsigned npos) +{ + if (npos >= m_nBitLength) + return false; + + deque::iterator it = m_word.begin() + npos; + m_word.erase(it); + + m_nBitLength++; + + return true; +} + +void CWord::Append(CBit b) +{ + m_word.push_back(b); + + m_nBitLength++; +} + +void CWord::Resize(unsigned nsize) +{ + m_word.resize(nsize); + m_nBitLength = nsize; +} + +bool CWord::PartShiftRight(unsigned nPos, unsigned nShift) +{ + if(nPos >= m_nBitLength) + return false; + + /*for (unsigned i = 0; i < nShift; i++) + { + m_word.insert() + }*/ + + return true; +} + +void CWord::Print() +{ + deque::iterator it; + for (it = m_word.begin(); it != m_word.end(); it++) + { + (*it).Print(); + } + printf("\r\n"); +} diff --git a/DRAMSys/simulator/src/error/ECC/Word.h b/DRAMSys/simulator/src/error/ECC/Word.h new file mode 100644 index 00000000..e3ae7c66 --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/Word.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include "Bit.h" + +using std::deque; + + +class CWord +{ +protected: + + unsigned m_nBitLength; + deque m_word; + + +public: + CWord(unsigned nBitLength); + virtual ~CWord(); + + CBit* GetAt(unsigned nBitPos); + + void Set(DWORD data); + void Rotate(); + + bool Insert(unsigned npos, CBit b); + bool Delete(unsigned npos); + + void Append(CBit b); + + void Resize(unsigned nsize); + + bool PartShiftRight(unsigned nPos, unsigned nShift); + + inline unsigned GetLength() const { return m_nBitLength; }; + + void Print(); + + CWord& operator=(DWORD d) + { + Set(d); + return *this; + } + + CBit& operator[](unsigned nPos) + { + return m_word.at(nPos); + } + + friend CWord operator >> (CWord l, const unsigned& r) + { + for (unsigned i = 0; i < r; i++) + { + l.m_word.pop_front(); + l.m_word.push_back(CBit(CBit::VALUE::ZERO)); + } + return l; + } +}; + From 10f9f2caff06cd5d77f260b6e99051bc599c6a53 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 27 Feb 2017 07:39:53 +0100 Subject: [PATCH 02/19] If StoreMode is Store or ErrorModel, then reads don't need data anymore. --- DRAMSys/simulator/src/simulation/StlPlayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DRAMSys/simulator/src/simulation/StlPlayer.cpp b/DRAMSys/simulator/src/simulation/StlPlayer.cpp index 2ed2dd5f..2b805500 100644 --- a/DRAMSys/simulator/src/simulation/StlPlayer.cpp +++ b/DRAMSys/simulator/src/simulation/StlPlayer.cpp @@ -113,7 +113,7 @@ void StlPlayer::nextPayload() unsigned long long addr = std::stoull(address.c_str(), 0, 16); // Get the data if necessary. - if (Configuration::getInstance().StoreMode != StorageMode::NoStorage) { + if (Configuration::getInstance().StoreMode != StorageMode::NoStorage && cmd != TLM_READ_COMMAND) { // The input trace file must provide the data to be stored into the memory. iss >> dataStr; if (dataStr.empty()) From af20dcb64708fb3414339e8598966bda837c0c7e Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 27 Feb 2017 08:57:34 +0100 Subject: [PATCH 03/19] ECC Controller as dummy created. --- DRAMSys/simulator/simulator.pro | 3 +- DRAMSys/simulator/src/error/controllerECC.h | 40 +++++++++++++++++++ .../simulator/src/simulation/Simulation.cpp | 8 +++- DRAMSys/simulator/src/simulation/Simulation.h | 4 +- 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 DRAMSys/simulator/src/error/controllerECC.h diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 593718da..3577b06b 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -169,7 +169,8 @@ HEADERS += \ src/controller/core/configuration/ConfigurationLoader.h \ src/error/errormodel.h \ src/simulation/ExampleInitiator.h \ - src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h + src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h \ + src/error/controllerECC.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h new file mode 100644 index 00000000..28c93547 --- /dev/null +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -0,0 +1,40 @@ +#ifndef CONTROLLERECC_H +#define CONTROLLERECC_H + +#include + +using namespace std; +using namespace tlm; + +struct ControllerECC: sc_module +{ + tlm_utils::multi_passthrough_target_socket t_socket; + tlm_utils::multi_passthrough_initiator_socket i_socket; + + SC_CTOR(ControllerECC) + : t_socket("t_socket") + , i_socket("i_socket") + { + t_socket.register_nb_transport_fw (this, &ControllerECC::nb_transport_fw); + i_socket.register_nb_transport_bw (this, &ControllerECC::nb_transport_bw); + } + + // Forward interface + + virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, sc_time& delay ) + { + return i_socket[id]->nb_transport_fw( trans, phase, delay ); + } + + + // Backward interface + + virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, sc_time& delay ) + { + return t_socket[id]->nb_transport_bw( trans, phase, delay ); + } +}; + +#endif // CONTROLLERECC_H diff --git a/DRAMSys/simulator/src/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index eae30c9a..c478e0bf 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -117,6 +117,10 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT // Create and properly initialize TLM recorders. They need to be ready before creating some modules. setupTlmRecorders(traceName, pathToResources, devices); + // Create ECC Controller + ecc = new ControllerECC("ecc"); + + // Create Arbiter arbiter = new Arbiter("arbiter"); arbiter->setTlmRecorders(tlmRecorders); @@ -142,7 +146,9 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT void Simulation::bindSockets() { - tSocket.bind(arbiter->tSocket); + tSocket.bind(ecc->t_socket); + ecc->i_socket(arbiter->tSocket); + //tSocket.bind(arbiter->tSocket); if(Configuration::getInstance().CheckTLM2Protocol) { for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) { diff --git a/DRAMSys/simulator/src/simulation/Simulation.h b/DRAMSys/simulator/src/simulation/Simulation.h index 45890b47..18304cbe 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.h +++ b/DRAMSys/simulator/src/simulation/Simulation.h @@ -49,7 +49,7 @@ #include "../controller/Controller.h" #include "../common/third_party/tinyxml2/tinyxml2.h" #include "../common/tlm2_base_protocol_checker.h" - +#include "../error/controllerECC.h" struct DramSetup { @@ -96,6 +96,8 @@ private: //TLM 2.0 Protocol Checkers std::vector*> controllersTlmCheckers; + // All transactions pass first through the ECC Controller + ControllerECC *ecc; // All transactions pass through the same arbiter Arbiter *arbiter; // Each DRAM unit has a controller From a0daa34bf14a79c3a6d6caa4b3c068e55a4f2126 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 27 Feb 2017 10:46:48 +0100 Subject: [PATCH 04/19] ECC implemented. Error trace created which produces many errors. --- .../resources/configs/mcconfigs/fifo.xml | 2 +- .../resources/configs/memspecs/WideIO.xml | 2 +- .../resources/simulations/sim-batch.xml | 8 +-- DRAMSys/simulator/src/error/controllerECC.h | 70 +++++++++++++------ .../src/simulation/SimulationManager.cpp | 3 +- 5 files changed, 57 insertions(+), 28 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml index 2048948f..b3810f64 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml @@ -10,5 +10,5 @@ - + diff --git a/DRAMSys/simulator/resources/configs/memspecs/WideIO.xml b/DRAMSys/simulator/resources/configs/memspecs/WideIO.xml index fbe252d6..3ab07172 100644 --- a/DRAMSys/simulator/resources/configs/memspecs/WideIO.xml +++ b/DRAMSys/simulator/resources/configs/memspecs/WideIO.xml @@ -24,7 +24,7 @@ - + diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index 0752914c..8e28fdb9 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -1,8 +1,8 @@ - - + + @@ -39,12 +39,12 @@ - + - chstone-adpcm_32.stl + test.stl diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 28c93547..b9dd772e 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -3,38 +3,66 @@ #include +#include "../common/xmlAddressdecoder.h" +#include "../common/DebugManager.h" + using namespace std; using namespace tlm; struct ControllerECC: sc_module { - tlm_utils::multi_passthrough_target_socket t_socket; - tlm_utils::multi_passthrough_initiator_socket i_socket; +private: + map m_mBuffer; - SC_CTOR(ControllerECC) - : t_socket("t_socket") - , i_socket("i_socket") - { - t_socket.register_nb_transport_fw (this, &ControllerECC::nb_transport_fw); - i_socket.register_nb_transport_bw (this, &ControllerECC::nb_transport_bw); - } +public: + tlm_utils::multi_passthrough_target_socket t_socket; + tlm_utils::multi_passthrough_initiator_socket i_socket; - // Forward interface + SC_CTOR(ControllerECC) + : t_socket("t_socket") + , i_socket("i_socket") + { + t_socket.register_nb_transport_fw(this, &ControllerECC::nb_transport_fw); + i_socket.register_nb_transport_bw(this, &ControllerECC::nb_transport_bw); + } - virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, - tlm::tlm_phase& phase, sc_time& delay ) - { - return i_socket[id]->nb_transport_fw( trans, phase, delay ); - } + // Forward interface + virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) + { + if(trans.get_command() == TLM_WRITE_COMMAND) + { + // Save all Bytes + for(unsigned i = 0; i < trans.get_data_length(); i++) + { + m_mBuffer[trans.get_address() + i] = *(trans.get_data_ptr() + i); + } + } + return i_socket[id]->nb_transport_fw( trans, phase, delay ); + } - // Backward interface + // Backward interface + virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) + { + if(trans.get_command() == TLM_WRITE_COMMAND) + { + // Compare all Bytes + for(unsigned i = 0; i < trans.get_data_length(); i++) + { + if(m_mBuffer[trans.get_address() + i] != *(trans.get_data_ptr() + i)) + { + std::stringstream msg; + msg << "Error Detected: Address: 0x" << hex << trans.get_address() + i + << "\n\t\tData Read: 0x" << hex << (int)*(trans.get_data_ptr() + i) + << "\n\t\tData original: 0x" << hex << (int)m_mBuffer[trans.get_address() + i]; - virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, - tlm::tlm_phase& phase, sc_time& delay ) - { - return t_socket[id]->nb_transport_bw( trans, phase, delay ); - } + DebugManager::getInstance().printDebugMessage(name(), msg.str()); + } + } + } + + return t_socket[id]->nb_transport_bw( trans, phase, delay ); + } }; #endif // CONTROLLERECC_H diff --git a/DRAMSys/simulator/src/simulation/SimulationManager.cpp b/DRAMSys/simulator/src/simulation/SimulationManager.cpp index a3494667..f9760533 100644 --- a/DRAMSys/simulator/src/simulation/SimulationManager.cpp +++ b/DRAMSys/simulator/src/simulation/SimulationManager.cpp @@ -92,7 +92,7 @@ void SimulationManager::runSimulations() for (auto& batch : simulationBatches) { boost::filesystem::path dir(exportPath); - boost::filesystem::create_directories(dir); + boost::filesystem::create_directory(dir); for (auto& dramSetup : batch.dramSetups) { @@ -238,6 +238,7 @@ void SimulationManager::runSimulation(string traceName) sc_set_stop_mode(SC_STOP_FINISH_DELTA); sc_start(); + double elapsed_secs = double(clock() - simStartTime) / CLOCKS_PER_SEC; report("\nSimulation took " + to_string(elapsed_secs) + " seconds\n"); delete simulation; From a11276c87658b7df45352d3a88eaa22c51ffadf7 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 2 Mar 2017 20:18:36 +0100 Subject: [PATCH 05/19] ECC Controller umgebaut. Testumgebung angepasst. Weak cells manuell gesetzt. --- DRAMSys/simulator/library.pro | 3 +- .../resources/configs/mcconfigs/fifo_ecc.xml | 20 ++++++ .../configs/memspecs/wideio_less_refresh.xml | 61 +++++++++++++++++++ .../configs/simulator/wideio_ecc.xml | 15 +++++ DRAMSys/simulator/resources/resources.pri | 7 +++ .../resources/simulations/wideio-ecc.xml | 22 +++++++ .../core/configuration/Configuration.cpp | 2 + .../core/configuration/Configuration.h | 1 + DRAMSys/simulator/src/error/controllerECC.h | 59 ++++++++++-------- DRAMSys/simulator/src/error/errormodel.cpp | 20 ++++++ DRAMSys/simulator/src/simulation/DRAMSys.cpp | 57 +++++++++++------ DRAMSys/simulator/src/simulation/main.cpp | 2 +- 12 files changed, 221 insertions(+), 48 deletions(-) create mode 100644 DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml create mode 100644 DRAMSys/simulator/resources/configs/memspecs/wideio_less_refresh.xml create mode 100644 DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml create mode 100644 DRAMSys/simulator/resources/simulations/wideio-ecc.xml diff --git a/DRAMSys/simulator/library.pro b/DRAMSys/simulator/library.pro index 0a930c9a..5a25d3ff 100644 --- a/DRAMSys/simulator/library.pro +++ b/DRAMSys/simulator/library.pro @@ -163,7 +163,8 @@ HEADERS += \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h \ src/simulation/TraceSetup.h \ src/simulation/DRAMSys.h \ - src/simulation/Setup.h + src/simulation/Setup.h \ + src/error/controllerECC.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml new file mode 100644 index 00000000..d6acf112 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/configs/memspecs/wideio_less_refresh.xml b/DRAMSys/simulator/resources/configs/memspecs/wideio_less_refresh.xml new file mode 100644 index 00000000..f8aa3190 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/memspecs/wideio_less_refresh.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml b/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml new file mode 100644 index 00000000..4b8ad3d1 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index fc1d85c7..37b75724 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -134,3 +134,10 @@ OTHER_FILES += resources/configs/thermalsim/mem.flp OTHER_FILES += resources/configs/thermalsim/powerInfo.xml OTHER_FILES += resources/configs/thermalsim/stack.stk OTHER_FILES += resources/configs/thermalsim/config.xml + +DISTFILES += \ + $$PWD/configs/simulator/wideio_ecc.xml \ + $$PWD/configs/mcconfigs/fifo_ecc.xml \ + $$PWD/simulations/wideio-ecc.xml \ + $$PWD/traces/test_ecc.stl \ + $$PWD/configs/memspecs/wideio_less_refresh.xml diff --git a/DRAMSys/simulator/resources/simulations/wideio-ecc.xml b/DRAMSys/simulator/resources/simulations/wideio-ecc.xml new file mode 100644 index 00000000..ead21319 --- /dev/null +++ b/DRAMSys/simulator/resources/simulations/wideio-ecc.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + test_ecc.stl + + diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 1a7feaa4..85f0a250 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -187,6 +187,8 @@ void Configuration::setParameter(std::string name, std::string value) NumberOfDevicesOnDIMM = string2int(value); else if(name == "CheckTLM2Protocol") CheckTLM2Protocol = string2bool(value); + else if(name == "EnableControllerECC") + EnableControllerECC = string2bool(value); // Specification for ErrorChipSeed, ErrorCSVFile path and StoreMode else if(name == "ErrorChipSeed") ErrorChipSeed = string2int(value); diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index 40c24b8a..bff51af5 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -81,6 +81,7 @@ struct Configuration bool SimulationProgressBar = false; unsigned int NumberOfDevicesOnDIMM = 1; bool CheckTLM2Protocol = false; + bool EnableControllerECC = false; // MemSpec (from DRAM-Power XML) MemSpec memSpec; diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index b9dd772e..0a33c1c1 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -12,7 +12,7 @@ using namespace tlm; struct ControllerECC: sc_module { private: - map m_mBuffer; + map> m_mBuffer; public: tlm_utils::multi_passthrough_target_socket t_socket; @@ -29,38 +29,45 @@ public: // Forward interface virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND) - { - // Save all Bytes - for(unsigned i = 0; i < trans.get_data_length(); i++) - { - m_mBuffer[trans.get_address() + i] = *(trans.get_data_ptr() + i); - } - } - return i_socket[id]->nb_transport_fw( trans, phase, delay ); + if(trans.get_command() == TLM_WRITE_COMMAND) + { + // Allocate memory if necessary + if(m_mBuffer[trans.get_address()].size() != trans.get_data_length()) + m_mBuffer[trans.get_address()].resize(trans.get_data_length()); + + // Copy data + memcpy(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); + } + return i_socket[id]->nb_transport_fw( trans, phase, delay ); } // Backward interface virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND) - { - // Compare all Bytes - for(unsigned i = 0; i < trans.get_data_length(); i++) - { - if(m_mBuffer[trans.get_address() + i] != *(trans.get_data_ptr() + i)) - { - std::stringstream msg; - msg << "Error Detected: Address: 0x" << hex << trans.get_address() + i - << "\n\t\tData Read: 0x" << hex << (int)*(trans.get_data_ptr() + i) - << "\n\t\tData original: 0x" << hex << (int)m_mBuffer[trans.get_address() + i]; - - DebugManager::getInstance().printDebugMessage(name(), msg.str()); - } - } - } + if(trans.get_command() == TLM_READ_COMMAND && phase == 3) + { + if(m_mBuffer[trans.get_address()].size() == trans.get_data_length()) + { + // Data can be compared, they got the same size + int error = memcmp(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); + if(error) + { + // Data not equal + cout << "\nError Detected: Address: 0x" << hex << trans.get_address(); + for(unsigned n = 0; n < trans.get_data_length(); n++) + { + if(m_mBuffer[trans.get_address()].data()[n] != trans.get_data_ptr()[n]) + { + cout << "\n\t\tError Byte " << dec << n << " Orig: 0x" << hex << (int)m_mBuffer[trans.get_address()].data()[n] + << " Read: 0x" << hex << (int)trans.get_data_ptr()[n]; + } + } + cout << endl; + } + } + } return t_socket[id]->nb_transport_bw( trans, phase, delay ); } }; diff --git a/DRAMSys/simulator/src/error/errormodel.cpp b/DRAMSys/simulator/src/error/errormodel.cpp index 4e397377..91eb789b 100644 --- a/DRAMSys/simulator/src/error/errormodel.cpp +++ b/DRAMSys/simulator/src/error/errormodel.cpp @@ -105,6 +105,26 @@ void errorModel::init() //weakCells[0].row = 0; //weakCells[0].dependent = true; + weakCells[0].bit = 0; + weakCells[0].col = 0; + weakCells[0].row = 0; + weakCells[0].dependent = false; + + weakCells[0].bit = 5; + weakCells[0].col = 0; + weakCells[0].row = 0; + weakCells[0].dependent = false; + + weakCells[0].bit = 12; + weakCells[0].col = 0; + weakCells[0].row = 0; + weakCells[0].dependent = false; + + weakCells[0].bit = 22; + weakCells[0].col = 0; + weakCells[0].row = 0; + weakCells[0].dependent = false; + markBitFlips(); } diff --git a/DRAMSys/simulator/src/simulation/DRAMSys.cpp b/DRAMSys/simulator/src/simulation/DRAMSys.cpp index 41b80d42..0cb5bbc5 100644 --- a/DRAMSys/simulator/src/simulation/DRAMSys.cpp +++ b/DRAMSys/simulator/src/simulation/DRAMSys.cpp @@ -58,6 +58,9 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, string simulationToRun, string pathToResources) : tSocket("DRAMSys_tSocket") { + // Initialize ecc pointer + ecc = 0; + logo(); // Read Configuration Setup: @@ -185,6 +188,10 @@ void DRAMSys::instantiateModules(const string &traceName, // They need to be ready before creating some modules. setupTlmRecorders(traceName, pathToResources); + // Initialize ECC Controller is enabled + if(Configuration::getInstance().EnableControllerECC) + ecc = new ControllerECC("ControllerECC"); + arbiter = new Arbiter("arbiter"); arbiter->setTlmRecorders(tlmRecorders); @@ -214,35 +221,45 @@ void DRAMSys::instantiateModules(const string &traceName, void DRAMSys::bindSockets() { - tSocket.bind(arbiter->tSocket); + // If ECC Controller enabled, put it between Trace and arbiter + if(Configuration::getInstance().EnableControllerECC) + { + tSocket.bind(ecc->t_socket); + ecc->i_socket.bind(arbiter->tSocket); + } + else + { + tSocket.bind(arbiter->tSocket); + } - if(Configuration::getInstance().CheckTLM2Protocol) + if(Configuration::getInstance().CheckTLM2Protocol) + { + for (size_t i = 0; + i < Configuration::getInstance().NumberOfMemChannels; + i++) { - for (size_t i = 0; - i < Configuration::getInstance().NumberOfMemChannels; - i++) - { - arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); - controllersTlmCheckers[i]->initiator_socket.bind( - controllers[i]->tSocket); - controllers[i]->iSocket.bind(drams[i]->tSocket); - } + arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); + controllersTlmCheckers[i]->initiator_socket.bind( + controllers[i]->tSocket); + controllers[i]->iSocket.bind(drams[i]->tSocket); } - else + } + else + { + for (size_t i = 0; + i < Configuration::getInstance().NumberOfMemChannels; + i++) { - for (size_t i = 0; - i < Configuration::getInstance().NumberOfMemChannels; - i++) - { - arbiter->iSocket.bind(controllers[i]->tSocket); - controllers[i]->iSocket.bind(drams[i]->tSocket); - } + arbiter->iSocket.bind(controllers[i]->tSocket); + controllers[i]->iSocket.bind(drams[i]->tSocket); } + } } DRAMSys::~DRAMSys() { - + if(ecc) + delete ecc; delete arbiter; for (auto controller : controllers) diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 18e00f77..18b474e9 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/ddr3-example.xml"; + SimulationXML = resources + "simulations/wideio-ecc.xml"; } std::vector players; From 20e6d4e6157e5dfc3c7bdde62620075dcb186d19 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Fri, 31 Mar 2017 16:09:36 +0200 Subject: [PATCH 06/19] ECC Controller erstellt ECC Daten. Noch Fehler bei der Weiterverarbeitung im Simulationsmodell. --- DRAMSys/simulator/library.pro | 10 +++- DRAMSys/simulator/src/error/ECC/Bit.cpp | 8 ++- DRAMSys/simulator/src/error/ECC/Bit.h | 9 ++- DRAMSys/simulator/src/error/ECC/ECC.cpp | 10 ++-- DRAMSys/simulator/src/error/ECC/Word.cpp | 41 ++++++++++++- DRAMSys/simulator/src/error/ECC/Word.h | 7 ++- DRAMSys/simulator/src/error/controllerECC.h | 66 ++++++++++++++++++--- DRAMSys/simulator/src/simulation/Dram.h | 3 + 8 files changed, 131 insertions(+), 23 deletions(-) diff --git a/DRAMSys/simulator/library.pro b/DRAMSys/simulator/library.pro index 5a25d3ff..50e6afa0 100644 --- a/DRAMSys/simulator/library.pro +++ b/DRAMSys/simulator/library.pro @@ -100,7 +100,10 @@ SOURCES += \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \ src/simulation/TraceSetup.cpp \ src/simulation/DRAMSys.cpp \ - src/simulation/Setup.cpp + src/simulation/Setup.cpp \ + src/error/ECC/Bit.cpp \ + src/error/ECC/ECC.cpp \ + src/error/ECC/Word.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -164,7 +167,10 @@ HEADERS += \ src/simulation/TraceSetup.h \ src/simulation/DRAMSys.h \ src/simulation/Setup.h \ - src/error/controllerECC.h + src/error/controllerECC.h \ + src/error/ECC/Bit.h \ + src/error/ECC/ECC.h \ + src/error/ECC/Word.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/error/ECC/Bit.cpp b/DRAMSys/simulator/src/error/ECC/Bit.cpp index b5faee9a..55f28ebf 100644 --- a/DRAMSys/simulator/src/error/ECC/Bit.cpp +++ b/DRAMSys/simulator/src/error/ECC/Bit.cpp @@ -1,6 +1,8 @@ -#include "stdafx.h" #include "Bit.h" +#include + +using std::cout; CBit::CBit(VALUE nVal) { @@ -16,10 +18,10 @@ void CBit::Print() { if (m_nValue == ZERO) { - printf("0"); + cout <<"0"; } else { - printf("1"); + cout << "1"; } } diff --git a/DRAMSys/simulator/src/error/ECC/Bit.h b/DRAMSys/simulator/src/error/ECC/Bit.h index 74aec5da..bfdda476 100644 --- a/DRAMSys/simulator/src/error/ECC/Bit.h +++ b/DRAMSys/simulator/src/error/ECC/Bit.h @@ -17,10 +17,17 @@ public: inline void Set() { m_nValue = ONE; }; inline void Clear() { m_nValue = ZERO; }; + inline unsigned Get() + { + if(m_nValue == ONE) + return 1; + else + return 0; + }; void Print(); - CBit& operator=(DWORD d) + CBit& operator=(unsigned d) { if (d == 0 ) { diff --git a/DRAMSys/simulator/src/error/ECC/ECC.cpp b/DRAMSys/simulator/src/error/ECC/ECC.cpp index bbd230ba..a041496e 100644 --- a/DRAMSys/simulator/src/error/ECC/ECC.cpp +++ b/DRAMSys/simulator/src/error/ECC/ECC.cpp @@ -1,5 +1,3 @@ -#include "stdafx.h" - #include "ECC.h" unsigned ECC::GetNumParityBits(unsigned nDataBits) @@ -31,7 +29,7 @@ void ECC::ExtendWord(CWord & v) void ECC::CalculateCheckbits(CWord & v, CWord & p) { - // Hamming-Code Prüfbits füllen + // Hamming-Code Prüfbits füllen unsigned i = 1, l = 0; while (i < v.GetLength()) { @@ -39,6 +37,8 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p) { for (unsigned k = 0; k < (i); k++) { + if(j + k >= v.GetLength()) + break; p[l] ^= v[j + k]; } } @@ -49,7 +49,7 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p) void ECC::InsertCheckbits(CWord& v, CWord p) { - // Prüfbits einfügen + // Prüfbits einfügen unsigned i = 1, j = 0; while (i <= v.GetLength()) { @@ -61,7 +61,7 @@ void ECC::InsertCheckbits(CWord& v, CWord p) void ECC::ExtractCheckbits(CWord v, CWord & p) { - // Prüfbits extrahieren + // Prüfbits extrahieren unsigned i = 1, j = 0; while(i <= v.GetLength()) { diff --git a/DRAMSys/simulator/src/error/ECC/Word.cpp b/DRAMSys/simulator/src/error/ECC/Word.cpp index a94bdad7..f260d76c 100644 --- a/DRAMSys/simulator/src/error/ECC/Word.cpp +++ b/DRAMSys/simulator/src/error/ECC/Word.cpp @@ -1,6 +1,8 @@ -#include "stdafx.h" #include "Word.h" +#include + +using std::cout; CWord::CWord(unsigned nBitLength) : m_nBitLength(nBitLength) @@ -23,7 +25,7 @@ CBit * CWord::GetAt(unsigned nBitPos) return nullptr; } -void CWord::Set(DWORD data) +void CWord::Set(unsigned data) { deque::iterator it; if (m_nBitLength < sizeof(data)) @@ -45,6 +47,29 @@ void CWord::Set(DWORD data) } } +void CWord::Set(unsigned char* data, unsigned lengthInBits) +{ + deque::iterator it; + if (m_nBitLength < lengthInBits) + { + it = m_word.begin(); + for (unsigned pos = 0; pos < m_nBitLength; pos++) + { + (*it) = data[pos>>3] & (1 << (7-(pos&7))); + it++; + } + } + else + { + unsigned pos = 0; + for (it = m_word.begin(); it != m_word.end(); it++) + { + (*it) = data[pos>>3] & (1 << (7-(pos&7))); + ++pos; + } + } +} + void CWord::Rotate() { deque buffer = m_word; @@ -113,5 +138,15 @@ void CWord::Print() { (*it).Print(); } - printf("\r\n"); + cout << "\r\n"; +} + +void CWord::Copy(unsigned char* ptr) +{ + unsigned pos = 0; + for(auto it = m_word.begin(); it != m_word.end(); it++) + { + ptr[pos>>3] |= (*it).Get() << (7-(pos&7)); + ++pos; + } } diff --git a/DRAMSys/simulator/src/error/ECC/Word.h b/DRAMSys/simulator/src/error/ECC/Word.h index e3ae7c66..f21432cb 100644 --- a/DRAMSys/simulator/src/error/ECC/Word.h +++ b/DRAMSys/simulator/src/error/ECC/Word.h @@ -20,12 +20,15 @@ public: CBit* GetAt(unsigned nBitPos); - void Set(DWORD data); + void Set(unsigned data); + void Set(unsigned char* data, unsigned lengthInBits); void Rotate(); bool Insert(unsigned npos, CBit b); bool Delete(unsigned npos); + void Copy(unsigned char* ptr); + void Append(CBit b); void Resize(unsigned nsize); @@ -36,7 +39,7 @@ public: void Print(); - CWord& operator=(DWORD d) + CWord& operator=(unsigned d) { Set(d); return *this; diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 0a33c1c1..94a2ce6e 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -3,6 +3,8 @@ #include +#include "ECC/ECC.h" + #include "../common/xmlAddressdecoder.h" #include "../common/DebugManager.h" @@ -29,14 +31,64 @@ public: // Forward interface virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND) - { - // Allocate memory if necessary - if(m_mBuffer[trans.get_address()].size() != trans.get_data_length()) - m_mBuffer[trans.get_address()].resize(trans.get_data_length()); + if(trans.get_command() == TLM_WRITE_COMMAND) + { + // Get data and length + unsigned nDataLength = trans.get_data_length(); + unsigned char* pData = trans.get_data_ptr(); - // Copy data - memcpy(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); + // Calculate how many 64 bit blocks are there + unsigned nBlocks = nDataLength>>3; + + // Create new data array for data with ECC + unsigned char* pDataECC = new unsigned char[nBlocks*9]; + memset(pDataECC, 0x0, nBlocks*9*sizeof(unsigned char)); + + // Create ECC data for every block + for(unsigned i = 0; i < nBlocks; i++) + { + // Create all variables needed for calulation + CWord dataword(64); + CWord checkbits(8); + + // Fill in current data block + dataword.Set(&pData[i<<3], 64); + dataword.Print(); + // Extend data word + ECC::ExtendWord(dataword); + + // Calculate Checkbits + ECC::CalculateCheckbits(dataword, checkbits); + ECC::InsertCheckbits(dataword, checkbits); + + // Calculate Parity + ECC::CalculateParityBit(dataword, checkbits[7]); + + // Copy old data + memcpy(&pDataECC[i*9], &pData[i<<3], 8); + + dataword.Print(); + checkbits.Print(); + + // Save new data + checkbits.Copy(&pDataECC[i*9+8]); + } + + // Change transport data length + trans.set_data_length(nBlocks*9); + + // delete old data + delete[] trans.get_data_ptr(); + + // Set new data + trans.set_data_ptr(pDataECC); + + // Allocate memory if necessary + //if(m_mBuffer[trans.get_address()].size() != trans.get_data_length()) + // m_mBuffer[trans.get_address()].resize(trans.get_data_length()); + + // Copy data + //memcpy(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); } return i_socket[id]->nb_transport_fw( trans, phase, delay ); } diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 3710a8ae..1e8079be 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -92,6 +92,9 @@ struct Dram : sc_module SC_CTOR(Dram) : tSocket("socket") { + if(Configuration::getInstance().EnableControllerECC) + bytesPerBurst += bytesPerBurst>>3; + std::uint64_t memorySize = Configuration::getInstance().getSimMemSizeInBytes(); // allocate and model storage of one DRAM channel using memory map memory = (unsigned char *)mmap(NULL, memorySize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, -1, 0); From 11d428c1d5b18331ecbbfe048cd9fe3351b01caf Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 13 Apr 2017 18:59:56 +0200 Subject: [PATCH 07/19] ECC implementierung fertig gestellt. --- ...CRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml | 55 ++++++ .../resources/configs/simulator/ddr3_ecc.xml | 22 +++ DRAMSys/simulator/resources/resources.pri | 5 +- .../resources/simulations/ddr3-ecc.xml | 22 +++ DRAMSys/simulator/src/error/ECC/ECC.cpp | 14 +- DRAMSys/simulator/src/error/controllerECC.h | 165 ++++++++++++++---- DRAMSys/simulator/src/error/errormodel.cpp | 7 +- DRAMSys/simulator/src/simulation/main.cpp | 2 +- 8 files changed, 252 insertions(+), 40 deletions(-) create mode 100644 DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml create mode 100644 DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml create mode 100644 DRAMSys/simulator/resources/simulations/ddr3-ecc.xml diff --git a/DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml b/DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml new file mode 100644 index 00000000..7a94a932 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml new file mode 100644 index 00000000..f1f7bcf8 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 37b75724..3d02ddb8 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -140,4 +140,7 @@ DISTFILES += \ $$PWD/configs/mcconfigs/fifo_ecc.xml \ $$PWD/simulations/wideio-ecc.xml \ $$PWD/traces/test_ecc.stl \ - $$PWD/configs/memspecs/wideio_less_refresh.xml + $$PWD/configs/memspecs/wideio_less_refresh.xml \ + $$PWD/simulations/ddr3-ecc.xml \ + $$PWD/configs/simulator/ddr3_ecc.xml \ + $$PWD/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml diff --git a/DRAMSys/simulator/resources/simulations/ddr3-ecc.xml b/DRAMSys/simulator/resources/simulations/ddr3-ecc.xml new file mode 100644 index 00000000..5760612c --- /dev/null +++ b/DRAMSys/simulator/resources/simulations/ddr3-ecc.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + test_ecc.stl + + diff --git a/DRAMSys/simulator/src/error/ECC/ECC.cpp b/DRAMSys/simulator/src/error/ECC/ECC.cpp index a041496e..b8e15743 100644 --- a/DRAMSys/simulator/src/error/ECC/ECC.cpp +++ b/DRAMSys/simulator/src/error/ECC/ECC.cpp @@ -31,13 +31,17 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p) { // Hamming-Code Prüfbits füllen unsigned i = 1, l = 0; - while (i < v.GetLength()) + + // Last bit is the parity bit - don't use this in the algorithm for hamming code + unsigned len = v.GetLength()-1; + + while (i < len) { - for (unsigned j = (i - 1); j < v.GetLength(); j += (i << 1)) + for (unsigned j = (i - 1); j < len; j += (i << 1)) { for (unsigned k = 0; k < (i); k++) { - if(j + k >= v.GetLength()) + if(j + k >= len) break; p[l] ^= v[j + k]; } @@ -51,7 +55,7 @@ void ECC::InsertCheckbits(CWord& v, CWord p) { // Prüfbits einfügen unsigned i = 1, j = 0; - while (i <= v.GetLength()) + while (i <= v.GetLength()-1) { v[i - 1] = p[j++]; i <<= 1; @@ -63,7 +67,7 @@ void ECC::ExtractCheckbits(CWord v, CWord & p) { // Prüfbits extrahieren unsigned i = 1, j = 0; - while(i <= v.GetLength()) + while(i <= v.GetLength()-1) { p[j++] = v[i - 1]; i <<= 1; diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 94a2ce6e..509e1036 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -31,7 +31,7 @@ public: // Forward interface virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND) + if(trans.get_command() == TLM_WRITE_COMMAND && trans.get_response_status() == TLM_INCOMPLETE_RESPONSE) { // Get data and length unsigned nDataLength = trans.get_data_length(); @@ -53,10 +53,12 @@ public: // Fill in current data block dataword.Set(&pData[i<<3], 64); - dataword.Print(); + // Extend data word ECC::ExtendWord(dataword); + checkbits = 0; + // Calculate Checkbits ECC::CalculateCheckbits(dataword, checkbits); ECC::InsertCheckbits(dataword, checkbits); @@ -67,13 +69,21 @@ public: // Copy old data memcpy(&pDataECC[i*9], &pData[i<<3], 8); - dataword.Print(); - checkbits.Print(); - // Save new data checkbits.Copy(&pDataECC[i*9+8]); } + // Print all +// for(unsigned i = 0; i < nBlocks; i++) +// { +// for(unsigned j = 0; j < 9; j++) +// { +// cout << setw(2) << setfill('0') << hex << uppercase << (int)pDataECC[i*9+j]; +// } +// cout << endl; +// } +// cout << endl; + // Change transport data length trans.set_data_length(nBlocks*9); @@ -82,14 +92,24 @@ public: // Set new data trans.set_data_ptr(pDataECC); - - // Allocate memory if necessary - //if(m_mBuffer[trans.get_address()].size() != trans.get_data_length()) - // m_mBuffer[trans.get_address()].resize(trans.get_data_length()); - - // Copy data - //memcpy(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); } + else if(trans.get_response_status() == TLM_INCOMPLETE_RESPONSE) + { + // 64 -> 72 + + // Get data length + unsigned nDataLength = trans.get_data_length(); + + // delete old data + delete[] trans.get_data_ptr(); + + // Set new data + nDataLength += nDataLength>>3; + trans.set_data_ptr(new unsigned char [nDataLength]); + + // Change transport data length + trans.set_data_length(nDataLength); + } return i_socket[id]->nb_transport_fw( trans, phase, delay ); } @@ -99,27 +119,108 @@ public: { if(trans.get_command() == TLM_READ_COMMAND && phase == 3) { - if(m_mBuffer[trans.get_address()].size() == trans.get_data_length()) - { - // Data can be compared, they got the same size - int error = memcmp(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); - if(error) - { - // Data not equal - cout << "\nError Detected: Address: 0x" << hex << trans.get_address(); + // Get data and length + unsigned nDataLength = trans.get_data_length(); + unsigned char* pData = trans.get_data_ptr(); - for(unsigned n = 0; n < trans.get_data_length(); n++) - { - if(m_mBuffer[trans.get_address()].data()[n] != trans.get_data_ptr()[n]) - { - cout << "\n\t\tError Byte " << dec << n << " Orig: 0x" << hex << (int)m_mBuffer[trans.get_address()].data()[n] - << " Read: 0x" << hex << (int)trans.get_data_ptr()[n]; - } - } - cout << endl; - } - } - } + // Calculate how many 72 bit blocks are there + unsigned nBlocks = nDataLength/9; + + // Print all +// for(unsigned i = 0; i < nBlocks; i++) +// { +// for(unsigned j = 0; j < 9; j++) +// { +// cout << setw(2) << setfill('0') << hex << uppercase << (int)pData[i*9+j]; +// } +// cout << endl; +// } +// cout << endl; + + // Verify ECC data for every block + for(unsigned i = 0; i < nBlocks; i++) + { + // Create all variables needed for calulation + CWord dataword(64); + CWord checkbits(8); + + // Fill in current data block + dataword.Set(&pData[i*9], 64); + checkbits.Set(&pData[i*9+8], 8); + + // Extend data word + ECC::ExtendWord(dataword); + + // Insert old checkbits + ECC::InsertCheckbits(dataword, checkbits); + ECC::InsertParityBit(dataword, checkbits[7]); + + checkbits = 0; + + // Calculate Checkbits + ECC::CalculateCheckbits(dataword, checkbits); + + // Calculate Parity + ECC::CalculateParityBit(dataword, checkbits[7]); + + // Translate Checkbits + bool bParity = checkbits[7] == CBit::ONE; + + unsigned char c = 0; + checkbits.Rotate(); + checkbits.Copy(&c); + c &= 0x7F; + + // Parity Error? + if(bParity) + { + // Parity Error + + if(c == 0) + { + // Only Parity Bit broken - continue + cout << "Parity Bit error" << endl; + continue; + } + else + { + // Data or Hamming Code Bit broken + cout << "Single Error Detected" << endl; + continue; + } + } + else + { + // No Parity Error + + if(c == 0) + { + // No error at all - continue + continue; + } + else + { + // Double error detected + cout << "Double Error Detected (Block " << i << ")." << endl; + continue; + } + } + } + // Change transport data length + trans.set_data_length(nBlocks<<3); + + // New Data + unsigned char* pDataECC = new unsigned char[nBlocks<<3]; + + // Copy data + memcpy(pDataECC, pData, nBlocks<<3); + + // delete old data + delete[] trans.get_data_ptr(); + + // Set new data + trans.set_data_ptr(pDataECC); + } return t_socket[id]->nb_transport_bw( trans, phase, delay ); } }; diff --git a/DRAMSys/simulator/src/error/errormodel.cpp b/DRAMSys/simulator/src/error/errormodel.cpp index 91eb789b..5ff3693f 100644 --- a/DRAMSys/simulator/src/error/errormodel.cpp +++ b/DRAMSys/simulator/src/error/errormodel.cpp @@ -49,7 +49,12 @@ void errorModel::init() burstLenght = Configuration::getInstance().memSpec.BurstLength; numberOfColumns = Configuration::getInstance().memSpec.NumberOfColumns; bytesPerColumn = xmlAddressDecoder::getInstance().amount["bytes"]; - numberOfRows = Configuration::getInstance().memSpec.NumberOfRows; + if(Configuration::getInstance().EnableControllerECC) + { + bytesPerColumn += bytesPerColumn>>3; + } + + numberOfRows = Configuration::getInstance().memSpec.NumberOfRows; numberOfBitErrorEvents = 0; diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 18b474e9..0bb75469 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/wideio-ecc.xml"; + SimulationXML = resources + "simulations/ddr3-ecc.xml"; } std::vector players; From e99b07fb4f6852080dd12edd3bbc013471617c9e Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 17 Apr 2017 15:48:31 +0200 Subject: [PATCH 08/19] Revert change in wideio.xml --- DRAMSys/simulator/resources/configs/memspecs/wideio.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DRAMSys/simulator/resources/configs/memspecs/wideio.xml b/DRAMSys/simulator/resources/configs/memspecs/wideio.xml index 3ab07172..fbe252d6 100644 --- a/DRAMSys/simulator/resources/configs/memspecs/wideio.xml +++ b/DRAMSys/simulator/resources/configs/memspecs/wideio.xml @@ -24,7 +24,7 @@ - + From a48fd2bfe6179c95f34383ed76a291b994a5d966 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 2 May 2017 17:12:13 +0200 Subject: [PATCH 09/19] DISTFILES from resources.pri changed to the standard way. --- DRAMSys/simulator/resources/resources.pri | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 37b75724..7d191a53 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -5,13 +5,14 @@ OTHER_FILES += resources/simulations/ddr3-example.xml OTHER_FILES += resources/simulations/ddr3-single-device.xml OTHER_FILES += resources/simulations/wideio-example.xml - +OTHER_FILES += resources/simulations/wideio-ecc.xml # Simulator Files OTHER_FILES += resources/configs/simulator/wideio.xml OTHER_FILES += resources/configs/simulator/ddr3.xml OTHER_FILES += resources/configs/simulator/ddr3-single-device.xml OTHER_FILES += resources/configs/simulator/wideio_thermal.xml +OTHER_FILES += resources/configs/simulator/wideio_ecc.xml # Scripts @@ -60,12 +61,14 @@ OTHER_FILES += resources/traces/mediabench-adpcmdecode_32.stl OTHER_FILES += resources/traces/ddr3_example.stl OTHER_FILES += resources/traces/ddr3_single_dev_example.stl OTHER_FILES += resources/traces/ddr3_SAMSUNG_M471B5674QH0_DIMM_example.stl +OTHER_FILES += resources/traces/test_ecc.stl # Memory Controller Configs OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml OTHER_FILES += resources/configs/mcconfigs/fifo.xml OTHER_FILES += resources/configs/mcconfigs/fr_fcfs.xml OTHER_FILES += resources/configs/mcconfigs/par_bs.xml +OTHER_FILES += resources/configs/mcconfigs/fifo_ecc.xml # Memspecs OTHER_FILES += resources/configs/memspecs/memspec.dtd @@ -108,6 +111,7 @@ OTHER_FILES += resources/configs/memspecs/MICRON_4Gb_LPDDR3-1600_32bit_A.xml OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B4G1646Q_4Gb_DDR3-1066_16bit.xml OTHER_FILES += resources/configs/memspecs/wideio.xml +OTHER_FILES += resources/configs/memspecs/wideio_less_refresh.xml # Address Mapping Configs OTHER_FILES += resources/configs/amconfigs/am_ddr3.xml @@ -134,10 +138,3 @@ OTHER_FILES += resources/configs/thermalsim/mem.flp OTHER_FILES += resources/configs/thermalsim/powerInfo.xml OTHER_FILES += resources/configs/thermalsim/stack.stk OTHER_FILES += resources/configs/thermalsim/config.xml - -DISTFILES += \ - $$PWD/configs/simulator/wideio_ecc.xml \ - $$PWD/configs/mcconfigs/fifo_ecc.xml \ - $$PWD/simulations/wideio-ecc.xml \ - $$PWD/traces/test_ecc.stl \ - $$PWD/configs/memspecs/wideio_less_refresh.xml From b3309eb2384635251a3d1dd4449eed569ea03a7b Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 4 May 2017 12:08:07 +0200 Subject: [PATCH 10/19] Added comments Reverted all configurations Adjusted resources.pri Added the enable switch for controllerECC to README.md --- .../resources/configs/simulator/ddr3_ecc.xml | 7 -- DRAMSys/simulator/resources/resources.pri | 4 +- DRAMSys/simulator/src/error/ECC/ECC.cpp | 52 +++++++++-- DRAMSys/simulator/src/error/ECC/ECC.h | 22 ++++- DRAMSys/simulator/src/error/controllerECC.h | 88 ++++++++++--------- DRAMSys/simulator/src/simulation/main.cpp | 2 +- README.md | 4 + 7 files changed, 118 insertions(+), 61 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml index f1f7bcf8..0d192422 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml @@ -12,11 +12,4 @@ - - diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 7d191a53..ac3384bf 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -6,6 +6,7 @@ OTHER_FILES += resources/simulations/ddr3-example.xml OTHER_FILES += resources/simulations/ddr3-single-device.xml OTHER_FILES += resources/simulations/wideio-example.xml OTHER_FILES += resources/simulations/wideio-ecc.xml +OTHER_FILES += resources/simulations/ddr3-ecc.xml # Simulator Files OTHER_FILES += resources/configs/simulator/wideio.xml @@ -13,7 +14,7 @@ OTHER_FILES += resources/configs/simulator/ddr3.xml OTHER_FILES += resources/configs/simulator/ddr3-single-device.xml OTHER_FILES += resources/configs/simulator/wideio_thermal.xml OTHER_FILES += resources/configs/simulator/wideio_ecc.xml - +OTHER_FILES += resources/configs/simulator/ddr3_ecc.xml # Scripts OTHER_FILES += resources/scripts/address_scrambler.pl @@ -112,6 +113,7 @@ OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B4G1646Q_4Gb_DDR3-1066_16bit.xml OTHER_FILES += resources/configs/memspecs/wideio.xml OTHER_FILES += resources/configs/memspecs/wideio_less_refresh.xml +OTHER_FILES += resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml # Address Mapping Configs OTHER_FILES += resources/configs/amconfigs/am_ddr3.xml diff --git a/DRAMSys/simulator/src/error/ECC/ECC.cpp b/DRAMSys/simulator/src/error/ECC/ECC.cpp index b8e15743..6cfaffe9 100644 --- a/DRAMSys/simulator/src/error/ECC/ECC.cpp +++ b/DRAMSys/simulator/src/error/ECC/ECC.cpp @@ -1,22 +1,32 @@ #include "ECC.h" +// ************************************************************************************************ +// Function which calculates the number of additional bits needed for a given number of data bits +// to store the hamming code and parity bit for a SECDED implementation unsigned ECC::GetNumParityBits(unsigned nDataBits) { unsigned nParityBits = 0; - // n = 2^k - k - 1 + // Function to calculate the nube of bits: n = 2^k - k - 1 + // ( Source: Hacker's Delight; p. 310; math. function 1 ) while (nDataBits > ((1 << nParityBits) - nParityBits - 1)) { ++nParityBits; } - return nParityBits+1; // +1 for SEC-DED + return nParityBits+1; // +1 for the parity bit } + +// ************************************************************************************************ +// Function which extends a given data word to the needed length for a SECDED code void ECC::ExtendWord(CWord & v) { unsigned end = v.GetLength() + ECC::GetNumParityBits(v.GetLength()); + // Insert x bits for the hamming code at positions where pos = 2^a; a = [0..N] + // In "Hacker's Delight" the smallest index is 1 - But in this beautiful C-Code it's 0 as it + // should be. That's why there is a '-1' in the call of v.Insert. unsigned i = 1; while (i < end) { @@ -24,17 +34,33 @@ void ECC::ExtendWord(CWord & v) i <<= 1; } + // Append one bit for the parity v.Append(CBit()); } +// ************************************************************************************************ +// Function which calculates the Hamming Code bits of an extended Data word. +// Function ExtendWord must be called before calling this function +// The calculated bits are stored in p, so the length of p should be at least +// 'GetNumParityBits(#data bits)-1' void ECC::CalculateCheckbits(CWord & v, CWord & p) { - // Hamming-Code Prüfbits füllen - unsigned i = 1, l = 0; + unsigned i = 1, l = 0; // Last bit is the parity bit - don't use this in the algorithm for hamming code unsigned len = v.GetLength()-1; + // Following Graph should show you the behaviour of this algorithm + // #Data bits: 11 #Hamming bits: 4 -> SECDED bits: 16 (incl. parity bit) + // Hamming Code Bit: | Bits used -> data(X)/Hamming Code(H) // Bit unused - + // 0 | H-X-X-X-X-X-X-X + // 1 | -HX--XX--XX--XX + // 2 | ---HXXX----XXXX + // 3 | -------HXXXXXXX + // For further information read "Hacker's delight" chapter 15 + // ATTENTION: The order of indices is different from the one in the book, + // but it doesn't matter in which order your data or check bits are. + // But it should be the same for encoding and decoding while (i < len) { for (unsigned j = (i - 1); j < len; j += (i << 1)) @@ -51,21 +77,26 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p) } } +// ************************************************************************************************ +// Function which inserts the checkbits which were calculated with 'CalculateCheckbits' in the +// extended data word. This is needed to calculate a proper parity of ALL bits to achive a SECDED +// behaviour. void ECC::InsertCheckbits(CWord& v, CWord p) { - // Prüfbits einfügen unsigned i = 1, j = 0; while (i <= v.GetLength()-1) { v[i - 1] = p[j++]; i <<= 1; } - } + +// ************************************************************************************************ +// Function which extracts the checkbits out of an extended data word. This is needed to check for +// bit error in the data word. void ECC::ExtractCheckbits(CWord v, CWord & p) { - // Prüfbits extrahieren unsigned i = 1, j = 0; while(i <= v.GetLength()-1) { @@ -74,6 +105,9 @@ void ECC::ExtractCheckbits(CWord v, CWord & p) } } +// ************************************************************************************************ +// Function which calculates the overal parity +// Simply XOR all bits void ECC::CalculateParityBit(CWord v, CBit & p) { // Paritybit @@ -84,11 +118,15 @@ void ECC::CalculateParityBit(CWord v, CBit & p) } } +// ************************************************************************************************ +// Function to insert the parity bit into the extended data word void ECC::InsertParityBit(CWord& v, CBit p) { v[v.GetLength() - 1] = p; } +// ************************************************************************************************ +// Function to extract the parity bit out of an extended data word. void ECC::ExtractParityBit(CWord v, CBit & p) { p = v[v.GetLength() - 1]; diff --git a/DRAMSys/simulator/src/error/ECC/ECC.h b/DRAMSys/simulator/src/error/ECC/ECC.h index 8379999a..3e9b8238 100644 --- a/DRAMSys/simulator/src/error/ECC/ECC.h +++ b/DRAMSys/simulator/src/error/ECC/ECC.h @@ -3,12 +3,30 @@ #include "Word.h" #include "Bit.h" +// ************************************************************************************************ +// +// | __/ __/ __| | __| _ _ _ __| |_(_)___ _ _ ___ +// | _| (_| (__ | _| || | ' \/ _| _| / _ \ ' \(_-< +// |___\___\___| |_| \_,_|_||_\__|\__|_\___/_||_/__/ +// +// ------------------------------------------------------------------------------------------------ +// ECC Implementation as described in "Hacker's Delight - second Edition" by Henry S. Warren, Jr. +// ------------------------------------------------------------------------------------------------ +// This namespace gives you some handy functions to get a SEC-DED implementation. +// +// SEC-DED: Single Error Correction - Double Error Detection +// This is the most common error correction code (ECC). +// It consists of two different correction codes: Haming code + parity code. +// +// For further details read chapter 15 of "Hacker's Delight - second Edition" +// ************************************************************************************************ + namespace ECC { - unsigned GetNumParityBits(unsigned nDataBits); - // Erweitert das Wort um zusätzliche Bits für die Berechnung des Hamming-Codes + // Extends the data word that it can be used with hamming code + // Several bits will be included at specific places void ExtendWord(CWord &v); void CalculateCheckbits(CWord &v, CWord & p); diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 509e1036..9ca85fe8 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -14,7 +14,7 @@ using namespace tlm; struct ControllerECC: sc_module { private: - map> m_mBuffer; + map m_mDataPointer; public: tlm_utils::multi_passthrough_target_socket t_socket; @@ -31,7 +31,7 @@ public: // Forward interface virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND && trans.get_response_status() == TLM_INCOMPLETE_RESPONSE) + if(trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_REQ) { // Get data and length unsigned nDataLength = trans.get_data_length(); @@ -69,47 +69,37 @@ public: // Copy old data memcpy(&pDataECC[i*9], &pData[i<<3], 8); - // Save new data + // Save hamming code + parity bit in the last byte checkbits.Copy(&pDataECC[i*9+8]); } - // Print all -// for(unsigned i = 0; i < nBlocks; i++) -// { -// for(unsigned j = 0; j < 9; j++) -// { -// cout << setw(2) << setfill('0') << hex << uppercase << (int)pDataECC[i*9+j]; -// } -// cout << endl; -// } -// cout << endl; - // Change transport data length trans.set_data_length(nBlocks*9); - // delete old data - delete[] trans.get_data_ptr(); + // store old data + m_mDataPointer[id] = trans.get_data_ptr(); // Set new data trans.set_data_ptr(pDataECC); } - else if(trans.get_response_status() == TLM_INCOMPLETE_RESPONSE) - { - // 64 -> 72 + else if(trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_REQ) + { + // 64 -> 72 - // Get data length - unsigned nDataLength = trans.get_data_length(); + // Get data length + unsigned nDataLength = trans.get_data_length(); - // delete old data - delete[] trans.get_data_ptr(); + // store old data + m_mDataPointer[id] = trans.get_data_ptr(); - // Set new data - nDataLength += nDataLength>>3; - trans.set_data_ptr(new unsigned char [nDataLength]); + // Set new data + nDataLength += nDataLength>>3; + trans.set_data_ptr(new unsigned char [nDataLength]); + + // Change transport data length + trans.set_data_length(nDataLength); + } - // Change transport data length - trans.set_data_length(nDataLength); - } return i_socket[id]->nb_transport_fw( trans, phase, delay ); } @@ -117,7 +107,7 @@ public: // Backward interface virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_READ_COMMAND && phase == 3) + if(trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_RESP) { // Get data and length unsigned nDataLength = trans.get_data_length(); @@ -126,17 +116,6 @@ public: // Calculate how many 72 bit blocks are there unsigned nBlocks = nDataLength/9; - // Print all -// for(unsigned i = 0; i < nBlocks; i++) -// { -// for(unsigned j = 0; j < 9; j++) -// { -// cout << setw(2) << setfill('0') << hex << uppercase << (int)pData[i*9+j]; -// } -// cout << endl; -// } -// cout << endl; - // Verify ECC data for every block for(unsigned i = 0; i < nBlocks; i++) { @@ -209,8 +188,11 @@ public: // Change transport data length trans.set_data_length(nBlocks<<3); - // New Data - unsigned char* pDataECC = new unsigned char[nBlocks<<3]; + // load data pointer + auto it = m_mDataPointer.find(id); + assert(it != m_mDataPointer.end()); + + unsigned char* pDataECC = it->second; // Copy data memcpy(pDataECC, pData, nBlocks<<3); @@ -221,6 +203,26 @@ public: // Set new data trans.set_data_ptr(pDataECC); } + else if(trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_RESP) + { + // 72 -> 64 + + // delete old data + delete[] trans.get_data_ptr(); + + // Get data length + unsigned nDataLength = trans.get_data_length(); + + // load data pointer + auto it = m_mDataPointer.find(id); + assert(it != m_mDataPointer.end()); + + trans.set_data_ptr(it->second); + + // Change transport data length + trans.set_data_length((nDataLength/9)<<3); + } + return t_socket[id]->nb_transport_bw( trans, phase, delay ); } }; diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 0bb75469..18e00f77 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/ddr3-ecc.xml"; + SimulationXML = resources + "simulations/ddr3-example.xml"; } std::vector players; diff --git a/README.md b/README.md index eb3e5f75..06e96cb6 100644 --- a/README.md +++ b/README.md @@ -544,6 +544,7 @@ Below, the sub-configurations are listed and explained. + ``` @@ -578,6 +579,9 @@ Below, the sub-configurations are listed and explained. - *CheckTLM2Protocol* (boolean) - "1": enables the TLM 2.0 Protocol Checking - "0": disables the TLM 2.0 Protocol Checking + - *EnableControllerECC* (boolean) + - "1": enables the ECC Controller with classic SECDED implementation + - "0": disables the ECC Controller with classic SECDED implementation - **Temperature Simulator Configuration** From 0b55dfd7e706939115a84991f74ea1cb26085e01 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 4 May 2017 12:22:31 +0200 Subject: [PATCH 11/19] Revert several changes. --- .../resources/configs/mcconfigs/fifo.xml | 2 +- DRAMSys/simulator/src/error/errormodel.cpp | 20 ------------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml index d6acf112..08135f13 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml @@ -15,6 +15,6 @@ - Store (store data without errormodel), - ErrorModel (store data with errormodel) --> - + diff --git a/DRAMSys/simulator/src/error/errormodel.cpp b/DRAMSys/simulator/src/error/errormodel.cpp index 5ff3693f..499d16f2 100644 --- a/DRAMSys/simulator/src/error/errormodel.cpp +++ b/DRAMSys/simulator/src/error/errormodel.cpp @@ -110,26 +110,6 @@ void errorModel::init() //weakCells[0].row = 0; //weakCells[0].dependent = true; - weakCells[0].bit = 0; - weakCells[0].col = 0; - weakCells[0].row = 0; - weakCells[0].dependent = false; - - weakCells[0].bit = 5; - weakCells[0].col = 0; - weakCells[0].row = 0; - weakCells[0].dependent = false; - - weakCells[0].bit = 12; - weakCells[0].col = 0; - weakCells[0].row = 0; - weakCells[0].dependent = false; - - weakCells[0].bit = 22; - weakCells[0].col = 0; - weakCells[0].row = 0; - weakCells[0].dependent = false; - markBitFlips(); } From 4d9a6f74d8d09235c8b9b061f62db4882f728a97 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 8 May 2017 10:13:57 +0200 Subject: [PATCH 12/19] ControllerECC: stored data pointer will be erased from map if not needed anymore. Moved {ErrorChipSeed, ErrorCSVFile, StoreMode} from mcconfig zu simconfig Error files moved to resources/error/ and are now named correctly. --- .../resources/configs/mcconfigs/fifo.xml | 8 - .../configs/mcconfigs/fifoStrict.xml | 8 - .../resources/configs/mcconfigs/fifo_ecc.xml | 8 - .../resources/configs/mcconfigs/fr_fcfs.xml | 8 - .../resources/configs/mcconfigs/par_bs.xml | 8 - .../configs/simulator/ddr3-single-device.xml | 8 + .../resources/configs/simulator/ddr3.xml | 8 + .../resources/configs/simulator/ddr3_ecc.xml | 8 + .../resources/configs/simulator/wideio.xml | 8 + .../configs/simulator/wideio_ecc.xml | 8 + .../configs/simulator/wideio_thermal.xml | 8 + .../error.csv => resources/error/wideio.csv} | 0 DRAMSys/simulator/resources/resources.pri | 3 + .../resources/simulations/sim-batch.xml | 52 +++ DRAMSys/simulator/src/error/controllerECC.h | 8 +- .../src/simulation/SimulationManager.cpp | 310 ++++++++++++++++++ 16 files changed, 420 insertions(+), 41 deletions(-) rename DRAMSys/simulator/{src/error/error.csv => resources/error/wideio.csv} (100%) create mode 100644 DRAMSys/simulator/resources/simulations/sim-batch.xml create mode 100644 DRAMSys/simulator/src/simulation/SimulationManager.cpp diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml index 08135f13..b09a4cfa 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml @@ -8,13 +8,5 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml index 5c58a9c5..7ca1a824 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml @@ -8,13 +8,5 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml index d6acf112..b09a4cfa 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml @@ -8,13 +8,5 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs.xml index fad8b021..0ff319b0 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs.xml @@ -8,14 +8,6 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/par_bs.xml b/DRAMSys/simulator/resources/configs/mcconfigs/par_bs.xml index 78a8afd7..63fb4a27 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/par_bs.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/par_bs.xml @@ -8,13 +8,5 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml index 35fd3dec..0a19ff35 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml @@ -11,4 +11,12 @@ + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3.xml index 9e322605..155ab0ff 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3.xml @@ -11,6 +11,14 @@ + + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/wideio.xml b/DRAMSys/simulator/resources/configs/simulator/wideio.xml index 8ba8f3ba..ba435056 100644 --- a/DRAMSys/simulator/resources/configs/simulator/wideio.xml +++ b/DRAMSys/simulator/resources/configs/simulator/wideio.xml @@ -10,5 +10,13 @@ + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml b/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml index 4b8ad3d1..3a7c43e5 100644 --- a/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml +++ b/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml @@ -11,5 +11,13 @@ + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/wideio_thermal.xml b/DRAMSys/simulator/resources/configs/simulator/wideio_thermal.xml index 42dcda72..880e573d 100644 --- a/DRAMSys/simulator/resources/configs/simulator/wideio_thermal.xml +++ b/DRAMSys/simulator/resources/configs/simulator/wideio_thermal.xml @@ -10,5 +10,13 @@ + + + + diff --git a/DRAMSys/simulator/src/error/error.csv b/DRAMSys/simulator/resources/error/wideio.csv similarity index 100% rename from DRAMSys/simulator/src/error/error.csv rename to DRAMSys/simulator/resources/error/wideio.csv diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index ac3384bf..b3f97407 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -140,3 +140,6 @@ OTHER_FILES += resources/configs/thermalsim/mem.flp OTHER_FILES += resources/configs/thermalsim/powerInfo.xml OTHER_FILES += resources/configs/thermalsim/stack.stk OTHER_FILES += resources/configs/thermalsim/config.xml + +# Error Simulation data +OTHER_FILES += resources/error/wideio.csv diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml new file mode 100644 index 00000000..0752914c --- /dev/null +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + chstone-adpcm_32.stl + + + + + diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 9ca85fe8..beefe784 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -194,6 +194,9 @@ public: unsigned char* pDataECC = it->second; + // delete data pointer from map + m_mDataPointer.erase(it); + // Copy data memcpy(pDataECC, pData, nBlocks<<3); @@ -219,7 +222,10 @@ public: trans.set_data_ptr(it->second); - // Change transport data length + // delete data pointer from map + m_mDataPointer.erase(it); + + // Change transport data length trans.set_data_length((nDataLength/9)<<3); } diff --git a/DRAMSys/simulator/src/simulation/SimulationManager.cpp b/DRAMSys/simulator/src/simulation/SimulationManager.cpp new file mode 100644 index 00000000..a3494667 --- /dev/null +++ b/DRAMSys/simulator/src/simulation/SimulationManager.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2015, University of 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 + */ + +#include +#include + +#include "SimulationManager.h" +#include "../common/Utils.h" + +using namespace std; +using namespace tinyxml2; + +SimulationManager::SimulationManager(string resources) : resources(resources) +{ +} + +SimulationManager::~SimulationManager() +{ + for (auto player : players) { + delete player; + } +#if USE_EXAMPLE_INITIATOR + delete init; + delete exampleInitiatorTlmChecker; +#endif + + for (auto tlmChecker : playersTlmCheckers) { + delete tlmChecker; + } +} + +void SimulationManager::loadSimulationsFromXML(string uri) +{ + cout << "\n\nload simulation-batch:" << endl; + cout << headline << endl; + + exportPath = getFileName(uri); + loadXML(uri, simulationdoc); + + cout << "\t-> parsing simulation objects .." << endl; + + XMLElement* simulation = simulationdoc.FirstChildElement("simulation"); + string xmlNodeName(simulation->Name()); + if( xmlNodeName != "simulation") + reportFatal("SimulationManager", "simulation node expected"); + parseSimulationBatch(simulation); + + cout << "\t-> simulation batches loaded successfully!\n" << endl; + + for (auto batch : simulationBatches) + { + batch.print(); + } +} + +void SimulationManager::runSimulations() +{ + for (auto& batch : simulationBatches) + { + boost::filesystem::path dir(exportPath); + boost::filesystem::create_directories(dir); + + for (auto& dramSetup : batch.dramSetups) + { + for (auto& traceSetup : batch.traceSetups) + { + string exportname = exportPath + "/" + traceSetup.first; + instantiateModules(exportname, dramSetup, traceSetup.second); + bindSockets(); + runSimulation(exportname); + } + } + } +} + +void SimulationManager::parseSimulationBatch(XMLElement* simulation) +{ + SimulationBatch batch; + + XMLElement* simconfig = simulation->FirstChildElement("simconfig"); + + XMLElement *thermalsimconfig = simulation->FirstChildElement("thermalsimconfig"); + + XMLElement* memspecs = simulation->FirstChildElement("memspecs"); + if(memspecs == NULL) memspecs = simulation; + + XMLElement* addressmappings = simulation->FirstChildElement("addressmappings"); + if(addressmappings == NULL) addressmappings = simulation; + + XMLElement* mcconfigs = simulation->FirstChildElement("mcconfigs"); + if(mcconfigs == NULL) mcconfigs = simulation; + + for (XMLElement* memspec = memspecs->FirstChildElement("memspec"); memspec != NULL; + memspec = memspec->NextSiblingElement("memspec")) + { + + for (XMLElement* addressmapping = addressmappings->FirstChildElement("addressmapping"); addressmapping != NULL; + addressmapping = addressmapping->NextSiblingElement("addressmapping")) + { + + for (XMLElement* mcconfig = mcconfigs->FirstChildElement("mcconfig"); + mcconfig != NULL; mcconfig = mcconfig->NextSiblingElement("mcconfig")) + { + batch.dramSetups.push_back(DramSetup(memspec, mcconfig, simconfig, addressmapping, thermalsimconfig)); + } + } + } + + addTraceSetups(batch, simulation); + + simulationBatches.push_back(batch); +} + +void SimulationManager::instantiateModules(string traceName, DramSetup dramSetup, vector traceSetup) +{ + + simulation = new Simulation("sim", resources, traceName, dramSetup, traceSetup); + +#if USE_EXAMPLE_INITIATOR + init = new ExampleInitiator("init"); + if(Configuration::getInstance().CheckTLM2Protocol) { + string str = "ExampleInitiatorTLMChecker"; + exampleInitiatorTlmChecker = new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); + } +#else + for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) { + std::string playerStr = "tracePlayer" + std::to_string(i); + TracePlayer *player; + sc_time playerClk; + + // The clock frequency for the player can be specified in the + // configuration file like in the example below (200 MHz): + // + // + // + // chstone-adpcm_32.stl + // + // + // + // If it is not specified in the configuration, the player will be + // configured to use the memory clock frequency got from the memory + // specs. + if (traceSetup[i].clkMhz == 0) + playerClk = Configuration::getInstance().memSpec.clk; + else + playerClk = FrequencyToClk(traceSetup[i].clkMhz); + const string pathToResources = resources; + player = new StlPlayer(playerStr.c_str(), pathToResources + string("traces/") + traceSetup[i].trace, playerClk, this); + if(Configuration::getInstance().SimulationProgressBar) + { + totalTransactions += player->getNumberOfLines(pathToResources + string("traces/") + traceSetup[i].trace); + } + players.push_back(player); + + if(Configuration::getInstance().CheckTLM2Protocol) { + string str = "TLMCheckerPlayer"+ std::to_string(i); + tlm_utils::tlm2_base_protocol_checker<> * playerTlmChecker = new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); + playersTlmCheckers.push_back(playerTlmChecker); + } + } + remainingTransactions = totalTransactions; +#endif /* USE_EXAMPLE_INITIATOR */ +} + +void SimulationManager::bindSockets() +{ +#if USE_EXAMPLE_INITIATOR + if(Configuration::getInstance().CheckTLM2Protocol) { + init->socket.bind(exampleInitiatorTlmChecker->target_socket); + exampleInitiatorTlmChecker->initiator_socket.bind(simulation->tSocket); + + } + else { + init->socket.bind(simulation->tSocket); +#else + if(Configuration::getInstance().CheckTLM2Protocol) { + for (size_t i = 0; i < players.size(); i++) { + players[i]->iSocket.bind(playersTlmCheckers[i]->target_socket); + playersTlmCheckers[i]->initiator_socket.bind(simulation->tSocket); + } + + } + else { + for (auto player : players) { + player->iSocket.bind(simulation->tSocket); + } + +#endif + } +} + +void SimulationManager::runSimulation(string traceName) +{ + report("\n\nStarting simulation:"); + report(headline); + report(" -> setup: \t\t" + getFileName(traceName)); + report(" -> memspec: \t\t" + Configuration::getInstance().memSpec.MemoryId); + cout << endl; + simStartTime = clock(); + + for (auto player : players) { + player->nextPayload(); + } + + sc_set_stop_mode(SC_STOP_FINISH_DELTA); + sc_start(); + double elapsed_secs = double(clock() - simStartTime) / CLOCKS_PER_SEC; + report("\nSimulation took " + to_string(elapsed_secs) + " seconds\n"); + delete simulation; +} + +void SimulationManager::startTraceAnalyzer() +{ + string p = getenv("trace"); + string run_tpr = p + " -f "; + run_tpr += "&"; + system(run_tpr.c_str()); +} + +void SimulationManager::addTraceSetups(SimulationBatch &batch, tinyxml2::XMLElement *simulation) +{ + vector devices; + XMLElement *tracesetups = simulation->FirstChildElement("tracesetups"); + XMLElement *simconfig = simulation->FirstChildElement("simconfig"); + unsigned int numberOfTracePlayers = 1; + XMLElement *ntp = simconfig->FirstChildElement("NumberOfTracePlayers"); + if (ntp != NULL) + ntp->QueryUnsignedAttribute("value", &numberOfTracePlayers); + + for (XMLElement *tracesetup = tracesetups->FirstChildElement("tracesetup"); tracesetup != NULL; tracesetup = tracesetup->NextSiblingElement("tracesetup")) { + for (XMLElement *device = tracesetup->FirstChildElement("device"); device != NULL; device = device->NextSiblingElement("device")) { + devices.push_back(Device(device->GetText(), device->IntAttribute("clkMhz"), device->IntAttribute("bl"))); + } + + // This step is done here to add a default device in case the user haven't specified a trace file to be executed by one or more trace players. + while (devices.size() < numberOfTracePlayers) { + devices.push_back(Device()); + } + + batch.traceSetups.emplace(tracesetup->Attribute("id"), devices); + devices.clear(); + } +} + +void inline SimulationManager::tracePlayerTerminates() +{ + static unsigned int finishedTracePlayers = 0; + finishedTracePlayers++; + + if (finishedTracePlayers == Configuration::getInstance().NumberOfTracePlayers) + simulation->terminateSimulation.notify(); +} +void inline SimulationManager::transactionFinished() +{ + remainingTransactions--; + loadbar(totalTransactions - remainingTransactions, totalTransactions); + if (remainingTransactions == 0) + { + cout << endl; + } +} +void SimulationManager::report(string message) +{ + cout << message << endl; +} + +void SimulationBatch::print() +{ + for (auto& s : traceSetups) + { + cout << "trace-setup " + s.first + ":\n"; + for (Device d : s.second) + cout << "\t(" << d.burstLength << ") " << d.trace << ";" << endl; + cout << endl; + } +} From 778834f15c534c5360e4fa1c423c3b7c189bcfb8 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Fri, 2 Jun 2017 17:19:19 +0200 Subject: [PATCH 13/19] Removed deprecated files --- .../resources/simulations/sim-batch.xml | 52 --- .../src/simulation/SimulationManager.cpp | 310 ------------------ 2 files changed, 362 deletions(-) delete mode 100644 DRAMSys/simulator/resources/simulations/sim-batch.xml delete mode 100644 DRAMSys/simulator/src/simulation/SimulationManager.cpp diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml deleted file mode 100644 index 0752914c..00000000 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - chstone-adpcm_32.stl - - - - - diff --git a/DRAMSys/simulator/src/simulation/SimulationManager.cpp b/DRAMSys/simulator/src/simulation/SimulationManager.cpp deleted file mode 100644 index a3494667..00000000 --- a/DRAMSys/simulator/src/simulation/SimulationManager.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2015, University of 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 - */ - -#include -#include - -#include "SimulationManager.h" -#include "../common/Utils.h" - -using namespace std; -using namespace tinyxml2; - -SimulationManager::SimulationManager(string resources) : resources(resources) -{ -} - -SimulationManager::~SimulationManager() -{ - for (auto player : players) { - delete player; - } -#if USE_EXAMPLE_INITIATOR - delete init; - delete exampleInitiatorTlmChecker; -#endif - - for (auto tlmChecker : playersTlmCheckers) { - delete tlmChecker; - } -} - -void SimulationManager::loadSimulationsFromXML(string uri) -{ - cout << "\n\nload simulation-batch:" << endl; - cout << headline << endl; - - exportPath = getFileName(uri); - loadXML(uri, simulationdoc); - - cout << "\t-> parsing simulation objects .." << endl; - - XMLElement* simulation = simulationdoc.FirstChildElement("simulation"); - string xmlNodeName(simulation->Name()); - if( xmlNodeName != "simulation") - reportFatal("SimulationManager", "simulation node expected"); - parseSimulationBatch(simulation); - - cout << "\t-> simulation batches loaded successfully!\n" << endl; - - for (auto batch : simulationBatches) - { - batch.print(); - } -} - -void SimulationManager::runSimulations() -{ - for (auto& batch : simulationBatches) - { - boost::filesystem::path dir(exportPath); - boost::filesystem::create_directories(dir); - - for (auto& dramSetup : batch.dramSetups) - { - for (auto& traceSetup : batch.traceSetups) - { - string exportname = exportPath + "/" + traceSetup.first; - instantiateModules(exportname, dramSetup, traceSetup.second); - bindSockets(); - runSimulation(exportname); - } - } - } -} - -void SimulationManager::parseSimulationBatch(XMLElement* simulation) -{ - SimulationBatch batch; - - XMLElement* simconfig = simulation->FirstChildElement("simconfig"); - - XMLElement *thermalsimconfig = simulation->FirstChildElement("thermalsimconfig"); - - XMLElement* memspecs = simulation->FirstChildElement("memspecs"); - if(memspecs == NULL) memspecs = simulation; - - XMLElement* addressmappings = simulation->FirstChildElement("addressmappings"); - if(addressmappings == NULL) addressmappings = simulation; - - XMLElement* mcconfigs = simulation->FirstChildElement("mcconfigs"); - if(mcconfigs == NULL) mcconfigs = simulation; - - for (XMLElement* memspec = memspecs->FirstChildElement("memspec"); memspec != NULL; - memspec = memspec->NextSiblingElement("memspec")) - { - - for (XMLElement* addressmapping = addressmappings->FirstChildElement("addressmapping"); addressmapping != NULL; - addressmapping = addressmapping->NextSiblingElement("addressmapping")) - { - - for (XMLElement* mcconfig = mcconfigs->FirstChildElement("mcconfig"); - mcconfig != NULL; mcconfig = mcconfig->NextSiblingElement("mcconfig")) - { - batch.dramSetups.push_back(DramSetup(memspec, mcconfig, simconfig, addressmapping, thermalsimconfig)); - } - } - } - - addTraceSetups(batch, simulation); - - simulationBatches.push_back(batch); -} - -void SimulationManager::instantiateModules(string traceName, DramSetup dramSetup, vector traceSetup) -{ - - simulation = new Simulation("sim", resources, traceName, dramSetup, traceSetup); - -#if USE_EXAMPLE_INITIATOR - init = new ExampleInitiator("init"); - if(Configuration::getInstance().CheckTLM2Protocol) { - string str = "ExampleInitiatorTLMChecker"; - exampleInitiatorTlmChecker = new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); - } -#else - for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) { - std::string playerStr = "tracePlayer" + std::to_string(i); - TracePlayer *player; - sc_time playerClk; - - // The clock frequency for the player can be specified in the - // configuration file like in the example below (200 MHz): - // - // - // - // chstone-adpcm_32.stl - // - // - // - // If it is not specified in the configuration, the player will be - // configured to use the memory clock frequency got from the memory - // specs. - if (traceSetup[i].clkMhz == 0) - playerClk = Configuration::getInstance().memSpec.clk; - else - playerClk = FrequencyToClk(traceSetup[i].clkMhz); - const string pathToResources = resources; - player = new StlPlayer(playerStr.c_str(), pathToResources + string("traces/") + traceSetup[i].trace, playerClk, this); - if(Configuration::getInstance().SimulationProgressBar) - { - totalTransactions += player->getNumberOfLines(pathToResources + string("traces/") + traceSetup[i].trace); - } - players.push_back(player); - - if(Configuration::getInstance().CheckTLM2Protocol) { - string str = "TLMCheckerPlayer"+ std::to_string(i); - tlm_utils::tlm2_base_protocol_checker<> * playerTlmChecker = new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); - playersTlmCheckers.push_back(playerTlmChecker); - } - } - remainingTransactions = totalTransactions; -#endif /* USE_EXAMPLE_INITIATOR */ -} - -void SimulationManager::bindSockets() -{ -#if USE_EXAMPLE_INITIATOR - if(Configuration::getInstance().CheckTLM2Protocol) { - init->socket.bind(exampleInitiatorTlmChecker->target_socket); - exampleInitiatorTlmChecker->initiator_socket.bind(simulation->tSocket); - - } - else { - init->socket.bind(simulation->tSocket); -#else - if(Configuration::getInstance().CheckTLM2Protocol) { - for (size_t i = 0; i < players.size(); i++) { - players[i]->iSocket.bind(playersTlmCheckers[i]->target_socket); - playersTlmCheckers[i]->initiator_socket.bind(simulation->tSocket); - } - - } - else { - for (auto player : players) { - player->iSocket.bind(simulation->tSocket); - } - -#endif - } -} - -void SimulationManager::runSimulation(string traceName) -{ - report("\n\nStarting simulation:"); - report(headline); - report(" -> setup: \t\t" + getFileName(traceName)); - report(" -> memspec: \t\t" + Configuration::getInstance().memSpec.MemoryId); - cout << endl; - simStartTime = clock(); - - for (auto player : players) { - player->nextPayload(); - } - - sc_set_stop_mode(SC_STOP_FINISH_DELTA); - sc_start(); - double elapsed_secs = double(clock() - simStartTime) / CLOCKS_PER_SEC; - report("\nSimulation took " + to_string(elapsed_secs) + " seconds\n"); - delete simulation; -} - -void SimulationManager::startTraceAnalyzer() -{ - string p = getenv("trace"); - string run_tpr = p + " -f "; - run_tpr += "&"; - system(run_tpr.c_str()); -} - -void SimulationManager::addTraceSetups(SimulationBatch &batch, tinyxml2::XMLElement *simulation) -{ - vector devices; - XMLElement *tracesetups = simulation->FirstChildElement("tracesetups"); - XMLElement *simconfig = simulation->FirstChildElement("simconfig"); - unsigned int numberOfTracePlayers = 1; - XMLElement *ntp = simconfig->FirstChildElement("NumberOfTracePlayers"); - if (ntp != NULL) - ntp->QueryUnsignedAttribute("value", &numberOfTracePlayers); - - for (XMLElement *tracesetup = tracesetups->FirstChildElement("tracesetup"); tracesetup != NULL; tracesetup = tracesetup->NextSiblingElement("tracesetup")) { - for (XMLElement *device = tracesetup->FirstChildElement("device"); device != NULL; device = device->NextSiblingElement("device")) { - devices.push_back(Device(device->GetText(), device->IntAttribute("clkMhz"), device->IntAttribute("bl"))); - } - - // This step is done here to add a default device in case the user haven't specified a trace file to be executed by one or more trace players. - while (devices.size() < numberOfTracePlayers) { - devices.push_back(Device()); - } - - batch.traceSetups.emplace(tracesetup->Attribute("id"), devices); - devices.clear(); - } -} - -void inline SimulationManager::tracePlayerTerminates() -{ - static unsigned int finishedTracePlayers = 0; - finishedTracePlayers++; - - if (finishedTracePlayers == Configuration::getInstance().NumberOfTracePlayers) - simulation->terminateSimulation.notify(); -} -void inline SimulationManager::transactionFinished() -{ - remainingTransactions--; - loadbar(totalTransactions - remainingTransactions, totalTransactions); - if (remainingTransactions == 0) - { - cout << endl; - } -} -void SimulationManager::report(string message) -{ - cout << message << endl; -} - -void SimulationBatch::print() -{ - for (auto& s : traceSetups) - { - cout << "trace-setup " + s.first + ":\n"; - for (Device d : s.second) - cout << "\t(" << d.burstLength << ") " << d.trace << ";" << endl; - cout << endl; - } -} From 7de21cf05603a8103421dca00b086c1e9506e0cc Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 8 Jun 2017 11:01:08 +0200 Subject: [PATCH 14/19] Configuration for ECC Controller extended to make it possible to add other ECC Controller --- .../configs/simulator/ddr3-single-device.xml | 1 + .../resources/configs/simulator/ddr3.xml | 1 + .../resources/configs/simulator/ddr3_ecc.xml | 2 +- .../resources/configs/simulator/wideio.xml | 1 + .../resources/configs/simulator/wideio_ecc.xml | 2 +- .../configs/simulator/wideio_thermal.xml | 1 + .../core/configuration/Configuration.cpp | 17 +++++++++++++++-- .../core/configuration/Configuration.h | 4 +++- DRAMSys/simulator/src/error/errormodel.cpp | 3 ++- DRAMSys/simulator/src/simulation/DRAMSys.cpp | 16 ++++++++++++---- DRAMSys/simulator/src/simulation/Dram.h | 2 +- DRAMSys/simulator/src/simulation/main.cpp | 2 +- README.md | 8 ++++---- 13 files changed, 44 insertions(+), 16 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml index 0a19ff35..354ad0d5 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml @@ -11,6 +11,7 @@ +