📄 vitham.c
字号:
/***********************************************************************************/
/* IS54 Baseband Simulation Software */
/* */
/* File Description : IS54 Viterbi Decoder Module */
/* File Name : vitham.c */
/* Date : 12/30/93 */
/* : July, 20001 - Modified for TMS320C55x project */
/* */
/* This file contains the routines used for the Viterbi decoding of a */
/* downlink IS54 slot. These routines assume a frame length of 89 bits */
/* (this includes 5 tail bits). Initial and final states are assumed */
/* to be [00000]. */
/* */
/* Functions : */
/* vitdec() : This routine is the main routine for this module. */
/* It should be called to Viterbi decode the slot. */
/* (i.e. to obtain the class-1 bits from the cc0[] and */
/* cc1[] bit streams) */
/* */
/* step_trellis() : This routine constructs the trellis (32 states) for */
/* a given bit number. */
/* */
/* Global Data : */
/* path_hist[] : This array contains the path history or 32-state */
/* trellis. It contains (89*32) elements where each */
/* element represents the previous bit state for the */
/* current bit state. Data is arranged according to */
/* the following example : */
/* prev_state = path_hist[ 32*bit_num + curr_state ] */
/* */
/***********************************************************************************/
/* Include Files */
/* Local Defines */
/* Function Prototypes */
void vitdec( unsigned*, unsigned*, unsigned* );
void step_trellis( int, int* );
/* Data */
int path_hist[89 * 32]; /* Path History Array */
/* Code */
/*************************************************************************/
/* Function : vitdec() */
/* */
/* Procedure : This routine Viterbi decodes a given IS54 downlink */
/* slot. It is passed pointers to 89-element bit arrays */
/* of cc0 and cc1 bit streams, and it viterbi decodes these */
/* into an 89-element bit array of class-1 bits. */
/* */
/* Inputs : */
/* cc0 : Pointer to 89-element bit array of cc1 bits */
/* for the current slot. */
/* */
/* cc1 : Pointer to 89-element bit array of cc1 bits */
/* for the current slot. */
/* */
/* Outputs : */
/* cl1 : Pointer to location where resultant 89-element */
/* class-1 bits stream should be stored. */
/* */
/* Return Code : */
/* NONE */
/* */
/*************************************************************************/
void vitdec( unsigned *cc0, unsigned *cc1, unsigned *cl1 )
{
int bit_num, *path_hist_ptr, state;
path_hist_ptr = path_hist;
for ( bit_num = 0; bit_num < 89; bit_num++ )
{
/* Traverse trellis for one time interval */
step_trellis( ((*(cc0++) << 1) | *(cc1++)), path_hist_ptr );
path_hist_ptr += 32;
}
/* Retrieve decoded output by back_tracking in time for state 0 */
/* back_track selected path in the trellis to generate output sequence. */
state = 0; /* Initial State = 0 */
cl1 += 88;
path_hist_ptr = path_hist + (88*32);
for( bit_num = 88; bit_num >= 0; bit_num-- )
{
*(cl1--) = ( state & 0x0001 ); /* Set cl1[] bit if state is odd */
state = *(path_hist_ptr + state); /* Get state for previous bit */
path_hist_ptr -= 32; /* Set history pointer for previous bit */
}
return;
}
/*************************************************************************/
/* Function : step_trellis() */
/* */
/* Procedure : */
/* This routine builds the 32-state path history for the */
/* current bit number. This routine is passed a pointer to the */
/* path history for the current bit in addition to a bit_pair */
/* parameter which contains the cc0 & cc1 bits for the current */
/* bit number. For each of states (0-31) for the current bit */
/* number, the state for the previous bit is stored. */
/* */
/* Inputs : */
/* bit_pair : This parameter should contain the current */
/* cc0 & cc1 bits in it's two LSB positions */
/* (in that order). All other bit positions should */
/* be zero. */
/* */
/* Outputs : */
/* path_hist_ptr : Pointer to path history for current bit. This */
/* routine will write previous bit states for */
/* current bit states (0-31). (a total of 32 */
/* elements will be written). */
/* */
/* Return Code : */
/* NONE */
/* */
/*************************************************************************/
void step_trellis( int bit_pair, int *path_hist_ptr )
{
int state, prev_state, output_di_bit, path1, path2, symbol;
int curr_dist[4], new_acc_dist[32];
static int acc_dist[32];
int euclid_dist[] = { 0, 1, 1, 2 };
int di_bit_lookup[32] = { 0, 3, 2, 1, 1, 2, 3, 0,
3, 0, 1, 2, 2, 1, 0, 3,
1, 2, 3, 0, 0, 3, 2, 1,
2, 1, 0, 3, 3, 0, 1, 2 };
/* Compute Euclidean Distance from each symbol */
for( symbol = 0; symbol < 4; symbol++ )
curr_dist[symbol] = euclid_dist[ symbol ^ bit_pair ];
/* Expand the trellis by one symbol interval */
for( state = 0; state < 32; state++ )
{
prev_state = state >> 1;
output_di_bit = di_bit_lookup[state];
path1 = acc_dist[ prev_state ] + curr_dist[ output_di_bit ];
path2 = acc_dist[ prev_state + 16 ] + curr_dist[ ~output_di_bit & 0x0003 ];
/* Select one of two paths entering a state */
if ( path1 < path2 )
{
new_acc_dist[state] = path1;
*(path_hist_ptr++) = prev_state; /* Previous Path State */
}
else
{
new_acc_dist[state] = path2;
*(path_hist_ptr++) = prev_state+16; /* Previous Path State */
}
}
/* Update Accumulated Distance metric */
for ( state = 0; state < 32; state++ )
acc_dist[state] = new_acc_dist[state];
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -