Added several files with test software for ECC Codes.

This commit is contained in:
Johannes Feldmann
2017-02-08 17:00:31 +01:00
parent cc8c378d0a
commit 6f0e2a00e1
7 changed files with 508 additions and 0 deletions

View 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");
}
}

View 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;
}
};

View 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];
}

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

View 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;
}

View 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");
}

View 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;
}
};