Added several files with test software for ECC Codes.
This commit is contained in:
25
DRAMSys/simulator/src/error/ECC/Bit.cpp
Normal file
25
DRAMSys/simulator/src/error/ECC/Bit.cpp
Normal file
@@ -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");
|
||||
}
|
||||
}
|
||||
66
DRAMSys/simulator/src/error/ECC/Bit.h
Normal file
66
DRAMSys/simulator/src/error/ECC/Bit.h
Normal file
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
91
DRAMSys/simulator/src/error/ECC/ECC.cpp
Normal file
91
DRAMSys/simulator/src/error/ECC/ECC.cpp
Normal file
@@ -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];
|
||||
}
|
||||
21
DRAMSys/simulator/src/error/ECC/ECC.h
Normal file
21
DRAMSys/simulator/src/error/ECC/ECC.h
Normal file
@@ -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);
|
||||
}
|
||||
128
DRAMSys/simulator/src/error/ECC/ECC_Test.cpp
Normal file
128
DRAMSys/simulator/src/error/ECC/ECC_Test.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
// ECC_Test.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <time.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
117
DRAMSys/simulator/src/error/ECC/Word.cpp
Normal file
117
DRAMSys/simulator/src/error/ECC/Word.cpp
Normal file
@@ -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<CBit>::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<CBit> 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<CBit>::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<CBit>::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<CBit>::iterator it;
|
||||
for (it = m_word.begin(); it != m_word.end(); it++)
|
||||
{
|
||||
(*it).Print();
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
60
DRAMSys/simulator/src/error/ECC/Word.h
Normal file
60
DRAMSys/simulator/src/error/ECC/Word.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include "Bit.h"
|
||||
|
||||
using std::deque;
|
||||
|
||||
|
||||
class CWord
|
||||
{
|
||||
protected:
|
||||
|
||||
unsigned m_nBitLength;
|
||||
deque<CBit> 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;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user