ECC Controller erstellt ECC Daten. Noch Fehler bei der Weiterverarbeitung im Simulationsmodell.

This commit is contained in:
Johannes Feldmann
2017-03-31 16:09:36 +02:00
parent cf0a7e0a79
commit 20e6d4e615
8 changed files with 131 additions and 23 deletions

View File

@@ -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) {

View File

@@ -1,6 +1,8 @@
#include "stdafx.h"
#include "Bit.h"
#include <iostream>
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";
}
}

View File

@@ -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 )
{

View File

@@ -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())
{

View File

@@ -1,6 +1,8 @@
#include "stdafx.h"
#include "Word.h"
#include <iostream>
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<CBit>::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<CBit>::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<CBit> 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;
}
}

View File

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

View File

@@ -3,6 +3,8 @@
#include <systemc.h>
#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 );
}

View File

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