Hey everyone, I am a brand new member and thought I could learn and get some help at the same time. I have an assignment that implements SECDED on a 16 bit word, storing the 5 checked bits and 1 parity bit in the upper 6 bits (makes a 22-bit word). Something is definitely not working and I'm a bit confused. Can someone take a look and point me in the right direction? Thanks.
#include <stdio.h>
#include "mem.h"
#include "secded.h"
/*
secded_store - called by the system to store a word (16-bits) of data.
Before storing the data in the error-prone memory using store, the
function should add check-bits and a parity bit for Single Error
Correction, Double Error Detection (SECDED).
The function store() will take a 22-bit value (since it takes an unsigned
long (32-bits), the high 10 bits will be cleared.
*/
void secded_store (unsigned long address, unsigned short data) {
unsigned long data_and_checkbits;
unsigned short lower;
unsigned int D[17],i, c1, c2, c4, c8, c16, parity, part1, part2;
lower = data & 0xffff;
// Compute the data bits
for (i=1;i<=16;i++) {
D[i] = (lower >> i) & 1;
}
// Compute the checked and parity bits
c1 = D[1] ^ D[3] ^ D[5] ^ D[7] ^ D[9] ^ D[11] ^ D[13] ^ D[15];
c2 = D[2] ^ D[3] ^ D[6] ^ D[7] ^ D[10] ^ D[11] ^ D[14] ^ D[15];
c4 = D[4] ^D[5] ^ D[6] ^ D[7] ^ D[11] ^ D[12] ^ D[13] ^ D[14] ^ D[15];
c8 = D[8] ^ D[9] ^ D[10] ^ D[11] ^ D[12] ^ D[13] ^ D[14] ^ D[15];
c16 = D[16];
part1 = D[1] ^ D[2] ^ D[3] ^ D[4] ^ D[5] ^ D[6] ^ D[7] ^ D[8];
part2 = D[9] ^ D[10] ^ D[11] ^ D[12] ^ D[13] ^ D[14] ^ D[15] ^ D[16];
parity = part1 ^ part2;
// Stores the checked and parity bits it the upper 6-bits of the data
unsigned long upper = lower | c1 << 16;
upper = upper | c2 << 17;
upper = upper | c4 << 18;
upper = upper | c8 << 19;
upper = upper | c16 << 20;
data_and_checkbits = upper | parity << 21;
store(address, data_and_checkbits);
}
/*
secded_load - called by the system to load a word (16-bits) of data.
After loading the data from the error-prone memory using load(), the
function should verify the validity of the data using the check-bits and
parity bit.
The function should return the data in the location pointed to by
data. The function should return 1 if there was an uncorrectable error
that was detected. It should return 0 if there were no errors or if the
errors were corrected.
*/
bool secded_load (unsigned long address, unsigned short& data) {
unsigned long unchecked_data;
unsigned int syndrome[5], c1, c2, c4, c8, c16, parity, part1, part2, pos;
unsigned int s_c1, s_c2, s_c4, s_c8, s_c16, s_parity, s_checkbits, checkbits;
unsigned short lower;
unchecked_data = load(address);
// Compute stored parity and checked bits
s_parity = (unchecked_data >> 21) & 1;
s_c16 = (unchecked_data >> 20) & 1;
s_c8 = (unchecked_data >> 19) & 1;
s_c4 = (unchecked_data >> 18) & 1;
s_c2 = (unchecked_data >> 17) & 1;
s_c1 = (unchecked_data >> 16) & 1;
unsigned int D[17],i;
lower = data & 0xffff;
// Compute the bits of data
for (i=1;i<=16;i++) {
D[i] = (lower >> i) & 1;
}
// Compute the checked and parity bits
c1 = D[1] ^ D[3] ^ D[5] ^ D[7] ^ D[9] ^ D[11] ^ D[13] ^ D[15];
c2 = D[2] ^ D[3] ^ D[6] ^ D[7] ^ D[10] ^ D[11] ^ D[14] ^ D[15];
c4 = D[4] ^D[5] ^ D[6] ^ D[7] ^ D[11] ^ D[12] ^ D[13] ^ D[14] ^ D[15];
c8 = D[8] ^ D[9] ^ D[10] ^ D[11] ^ D[12] ^ D[13] ^ D[14] ^ D[15];
c16 = D[16];
part1 = D[1] ^ D[2] ^ D[3] ^ D[4] ^ D[5] ^ D[6] ^ D[7] ^ D[8];
part2 = D[9] ^ D[10] ^ D[11] ^ D[12] ^ D[13] ^ D[14] ^ D[15] ^ D[16];
parity = part1 ^ part2;
s_checkbits = s_c1 ^ s_c2 ^ s_c4 ^ s_c8 ^ s_c16;
checkbits = c1 ^ c2 ^ c4 ^ c8 ^c16;
// Compute syndrome word
syndrome[0] = c1 ^ s_c1;
syndrome[1] = c2 ^ s_c2;
syndrome[2] = c4 ^ s_c4;
syndrome[3] = c8 ^ s_c8;
syndrome[4] = c16 ^ s_c16;
// Computes the position of the flipped bit
pos = 0;
if (syndrome[0] == 1){
pos++;
}else if (syndrome[1] == 1) {
pos+=2;
}else if (syndrome[2] == 1) {
pos+=4;
}else if (syndrome[3] == 1) {
pos+=8;
}else if (syndrome[4] == 1) {
pos+=16;
}
// No error
if ((s_parity == parity) && (s_checkbits == checkbits)){
data = unchecked_data;
return true;
}
// Single-bit error
if ((s_parity == parity) && (s_checkbits != checkbits)) {
data = unchecked_data ^ (1 << (pos-1)); // Go to bit with error and toggle it
return true;
}
// Parity bit is flipped
if ((s_parity != parity) && (s_checkbits == checkbits)) {
data = unchecked_data ^ (1 << 20); // Toggle the parity bit
return true;
}
// Two-bit error
if ((s_parity != parity) && (s_checkbits != checkbits)) {
return false;
}
}