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);