📄 viterbi_turbo2.c
字号:
/*****************************************************************************//* FIle Name : viterbi_turbo2.c *//* Description : WiMax FEC Viterbi Decoder for BTC *//* author : miffie *//* Date : Nov/19/05 *//* Copyright (c) 2005 miffie All rights reserved. *//*****************************************************************************///One line correction in turbo decoder will be done through 3 pipeline stages//#1 check metrics calculation in normal order// write into Soft memory (in first row iteration )//#2 Error estimation in reverse order// read from Soft memory// write into path memory//#3 trace back with SoftOutput// read from both Soft memory & pathmemory// write back to Soft memory//In this viterbi_turbo2, #2  are exercised.struct binaryset viterbi_turbo2 (char type, struct binaryset datain , struct binaryset metric, char *parity ) {int ii , jj , kk ;char nn , pp ;short tmp0, tmp1, tmp2 ;struct binaryset bset ;short brmetric[4] ;short metric0[128], metric1[128] ;short minimum_metric ;short won_metric ;char state[128][4] ;char branch[128] ;char pathmem[64][128] ; short MAX_METRIC = 0x7f ;char SISO_SHIFT = 4 ;char BRANCH_OFFSET = 1 ; //Main PRINTF( "viterbi_turbo2.c size=%x parity=%d\n", datain.size,*parity) ; if (type<4) { //Hamming code //initialize nn = (type==1) ? 0x1f : (type==2) ? 0x3f : 0x7f ; pp = (type==1) ? 0x5 : //lfsr+parity length (type==2) ? 0x6 : 0x7 ; for(ii=0;ii<=nn;ii++) { //init state[ii][0] = ((lfsr( type, 0 , (ii>>1) ) & nn)<<1) + ((ii&0x1) ? 1 : 0) ; //parity state[ii][1] = ((lfsr( type, 1 , (ii>>1) ) & nn)<<1) + ((ii&0x1) ? 0 : 1) ; //parity } //init //for(ii=0;ii<=nn;ii++) printf("state(%x %x) %x\n", ii, 0, state[ii][0] ) ; //for(ii=0;ii<=nn;ii++) printf("state(%x %x) %x\n", ii, 1, state[ii][1] ) ;////////////////////////////////////////////////////////////////////#2 Error estimation in reverse order////////////////////////////////////////////////////////////////// //initialize metrics for(ii=0;ii<=nn;ii++) { //each state metric0[ii] = metric.data[ii>>1] ; if(( *parity<0 ) & (ii%2)) metric0[ii] -= *parity ; if(( *parity>0 ) & ((ii%2)==0)) metric0[ii] += *parity ; } //each state for(ii=datain.size-1;ii>=0;ii--) { //each cycle in normal order //branch metric //state0-31 brmetric[0] = (datain.data[ii]>=8) ? 0xf-datain.data[ii] : datain.data[ii] ; brmetric[0] += BRANCH_OFFSET; brmetric[1] = 0xf - brmetric[0] ; minimum_metric = MAX_METRIC ; //metric for(jj=0;jj<=nn;jj++) { //each state if ( ii == datain.size-1) {//parity tmp0 = jj ; tmp1 = jj ^0x01 ; } else { tmp0 = state[jj][0] ; tmp1 = state[jj][1] ; } //parity //printf("%d %x metric[%x]=%x+br%x metric[%x]=%x+br%x\n", // ii, jj, tmp0, metric0[tmp0], brmetric[0], tmp1, metric0[tmp1], brmetric[1] ) ; tmp0 = metric0[tmp0] + brmetric[0] ; tmp0 = (tmp0>MAX_METRIC) ? MAX_METRIC : tmp0 ; tmp1 = metric0[tmp1] + brmetric[1] ; tmp1 = (tmp1>MAX_METRIC) ? MAX_METRIC : tmp1 ; pathmem[ii][jj] = tmp0 - tmp1 ; //printf("pathmem( %d, %x %d ) =%d\n",ii, (jj>>1), (jj&0x1), pathmem[ii][jj] ) ; metric1[jj] = (tmp0>=tmp1) ? tmp1 : tmp0 ; //min(tmp0,tmp1) ; //limitter if (metric1[jj] > MAX_METRIC ) metric1[jj] = MAX_METRIC ; //printf("%d metric[%d]=%d\n", ii, jj, metric1[jj] ) ; if (metric1[jj] < minimum_metric) { minimum_metric = metric1[jj] ; won_metric = jj ; } } //each state //printf("%d won_metric = %x %x\n", ii, won_metric>>1 , won_metric&0x1 ) ; //printf("%d pathmem1(%x) = %x\n", ii, won_metric, pathmem1[won_metric]) ; for(jj=0;jj<=nn;jj++) { //each metric1 //Normalization metric1[jj] -= minimum_metric ; //force the won_metric to zero //copy metric1 to metric0 for the next cycle operation metric0[jj] = metric1[jj] ; //copy metric1 to metric0 for the next cycle operation } //each metric1 } //each cycle ////////////////////////////////////////////////////////////////////#3 trace back with SoftOutput////////////////////////////////////////////////////////////////// //output *parity = 0 ; won_metric=0 ; //because check should be zero at the end of calcuration for(jj=0;jj<datain.size;jj++) { //output tmp1 = pathmem[jj][won_metric] ; printf("datain.data(%d)=%x path(%x)=%x ", jj, datain.data[jj], won_metric, tmp1&0xff) ; //SISO Softin Softout datain.data[jj] = ((tmp1>=0)&(datain.data[jj]<8)) ? datain.data[jj]+2 : ((tmp1>=0)&(datain.data[jj]>=8)) ? datain.data[jj]-2 : datain.data[jj] ; /***** //Following complicated solution did not work well. //Because some corrections will not be right, it's dangerous to change //Soft data, which is not assumed to be corrected. Miffie Nov/19/05 datain.data[jj] = ((tmp1<0)&(datain.data[jj]==0)) ? 0 : ((tmp1<0)&(datain.data[jj]<8)) ? datain.data[jj]+(tmp1>>SISO_SHIFT) : ((tmp1<0)&(datain.data[jj]==0xf)) ? 0xf : (tmp1<0) ? datain.data[jj]-(tmp1>>SISO_SHIFT) : ((tmp1>=0)&(datain.data[jj]<8)) ? 8+(tmp1>>SISO_SHIFT) : 7-(tmp1>>SISO_SHIFT) ; datain.data[jj] = (datain.data[jj]<0 ) ? 0 : (datain.data[jj]>0xf) ? 0xf : datain.data[jj] ; *******/ printf("=>%x\n", datain.data[jj]) ; *parity ^= (datain.data[jj]>=8) ? 1 : 0 ; if ( tmp1 >= 0 ) won_metric = state[won_metric][1] ; else won_metric = state[won_metric][0] ; } //output } //Hamming code else { //parity only *parity = 0 ; for(jj=0;jj<datain.size;jj++) { //parity *parity ^= (datain.data[jj]>=8) ? 1 : 0 ; } //parity if (parity==0) {// no parity error for(jj=0;jj<datain.size;jj++) { //each sample datain.data[jj] = (datain.data[jj]==0 ) ? 0 : (datain.data[jj]==0xf) ? 0xf : (datain.data[jj]>=8) ? datain.data[jj] +1 : datain.data[jj] -1 ; } //each sample } //no parity errors else { //error for(jj=0;jj<datain.size;jj++) { //each sample datain.data[jj] = (datain.data[jj]>=8) ? datain.data[jj] -1 : datain.data[jj] +1 ; } //each sample } //error } //parity only free( metric.data ) ; return ( datain ) ;} //viterbi_turbo2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -