Commit 857a24b4 authored by sydney's avatar sydney

Fixed reds decoder bugs

parent bb564d05
......@@ -3,38 +3,59 @@
CDecoder_MS_fixed_reds::CDecoder_MS_fixed_reds()
{
const size_t nb_edges = _M;
const size_t vn_deg = DEG_2;
const size_t cn_deg = DEG_1;
const size_t nb_rows = _K;
const size_t nb_cols = _N;
size_t row;
size_t vn_slot_offset, cn_slot_offset;
size_t vn_idx;
p_vn_addr = new char *[nb_edges];
p_cn_addr = new char *[nb_edges];
// We allocate a max of cn_deg_max per CN
p_vn_addr = new char *[nb_cols * cn_deg_max];
// We allocate a max of vn_deg_max per VN
p_cn_addr = new char *[nb_cols * vn_deg_max];
for(size_t i = 0; i < nb_edges; i++) {
p_vn_addr[i] = NULL;
for(size_t i = 0; i < nb_rows*cn_deg_max; i++) {
p_cn_addr[i] = NULL;
}
for(size_t i = 0; i < nb_cols*vn_deg_max; i++) {
p_vn_addr[i] = NULL;
}
/* Iterate over the entire matrix H */
for(size_t edge_idx = 0; edge_idx < nb_edges; edge_idx++) {
vn_idx = PosNoeudsVariable[edge_idx];
row = edge_idx / cn_deg; // Also indicates the current CN
/* The following line is quite problematic. We assume that all CNs
* have the same degree like it is the case with a DVB-S2 LDPC code.
* (excluding the last CN, but it's not a problem here).
*
* What if the code has variable degree per CN ?
*/
row = edge_idx / cn_deg_max; // Also indicates the current CN
// Find the next empty slot
vn_slot_offset = 0;
cn_slot_offset = 0;
while(p_vn_addr[row*cn_deg + vn_slot_offset] != NULL) vn_slot_offset++;
while(p_cn_addr[vn_idx*vn_deg + cn_slot_offset] != NULL) cn_slot_offset++;
while(p_vn_addr[row*cn_deg_max + vn_slot_offset] != NULL) {
vn_slot_offset++;
if(vn_slot_offset == cn_deg_max) {
std::cout << "offset out of bound" << std::endl;
break;
}
}
while(p_cn_addr[vn_idx*vn_deg_max + cn_slot_offset] != NULL) {
cn_slot_offset++;
if(cn_slot_offset == vn_deg_max) {
std::cout << "offset out of bound" << std::endl;
break;
}
}
p_vn_addr[row*cn_deg + vn_slot_offset] =
&var_msgs[vn_idx*vn_deg + vn_slot_offset];
p_cn_addr[vn_idx*vn_deg + cn_slot_offset] =
&check_msgs[row*cn_deg + cn_slot_offset];
p_vn_addr[row*cn_deg_max + vn_slot_offset] =
&var_msgs[vn_idx*vn_deg_max + vn_slot_offset];
p_cn_addr[vn_idx*vn_deg_max + cn_slot_offset] =
&check_msgs[row*cn_deg_max + cn_slot_offset];
}
}
......@@ -54,11 +75,11 @@ void CDecoder_MS_fixed_reds::decode(
char *vn = CDecoder_fixed_reds::var_nodes;
char *vn_msgs = CDecoder_fixed_reds::var_msgs;
char *cn_msgs = CDecoder_fixed_reds::check_msgs;
size_t vn_deg = vn_deg_max;
size_t cn_deg = cn_deg_max;
const size_t nb_vn = _N; // _N is number of VN
const size_t nb_cn = _K; // _K is number of CN
const size_t nb_edges = _M; // _M is number of "messages" or "edges"
const size_t vn_deg = DEG_2;
const size_t cn_deg = DEG_1;
const char threshold = 0; // TODO : check value
/* Initialize variable node messages */
......@@ -80,6 +101,10 @@ void CDecoder_MS_fixed_reds::decode(
char global_minLLR = 0x7F;
char vn_to_cn_msgs[cn_deg];
/* FIXME : in DVB-S2, the H matrix has one row with different degree:
* the last one. */
cn_deg = cn_idx == (nb_cn-1) ? DEG_2 : cn_deg;
/* First we retrieve all messages of VNs neighboring the current CN */
for(size_t edge_idx = 0; edge_idx < cn_deg; edge_idx++) {
vn_to_cn_msgs[edge_idx] = *p_vn_addr[cn_idx*cn_deg + edge_idx];
......@@ -113,11 +138,19 @@ void CDecoder_MS_fixed_reds::decode(
*/
for(size_t vn_idx = 0; vn_idx < nb_vn; vn_idx++) {
vn[vn_idx] = llr_vn[vn_idx];
for(size_t edge_idx = 0; edge_idx < vn_deg; edge_idx++) {
for(
size_t edge_idx = 0;
edge_idx < vn_deg && p_cn_addr[vn_idx*vn_deg + edge_idx] != NULL;
edge_idx++)
{
vn[vn_idx] += *p_cn_addr[vn_idx*vn_deg + edge_idx];
}
for(size_t edge_idx = 0; edge_idx < vn_deg; edge_idx++) {
for(
size_t edge_idx = 0;
edge_idx < vn_deg && p_cn_addr[vn_idx*vn_deg + edge_idx] != NULL;
edge_idx++)
{
vn_msgs[vn_idx*vn_deg + edge_idx] =
vn[vn_idx] - *p_cn_addr[vn_idx*vn_deg + edge_idx];
}
......
......@@ -5,9 +5,9 @@
CDecoder_fixed_reds::CDecoder_fixed_reds()
{
//var_nodes = new char[NOEUD];
var_msgs = new char[MESSAGE];
check_msgs = new char[MESSAGE];
var_nodes = new char[NOEUD];
var_msgs = new char[vn_deg_max * _N];
check_msgs = new char[cn_deg_max * _K];
}
CDecoder_fixed_reds::~CDecoder_fixed_reds()
......
......@@ -11,6 +11,8 @@
class CDecoder_fixed_reds : public CDecoder_fixed {
protected:
const size_t cn_deg_max = DEG_1;
const size_t vn_deg_max = 8; // FIXME : find this constant somewhere
char *var_msgs;
char *check_msgs;
char *var_nodes;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment