📄 channel_coding.c
字号:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <windows.h>
#include "wimax.h"
//Channel Coding/Decoding
//Convolutional Coding (5,7), (2,1,2), K=3
void convolutional_coding(int input[],int output[],int data_len)
{
int i;
int state=0;
for(i=0;i<data_len;i++)
{
switch(state)
{
case 0: // if state = S0 '00'
if(input[i] == 0){ // input 0 state=S0 output 00
state=0;
output[i*2]=0;
output[i*2+1]=0;
} else if(input[i] == 1) { // input 1 state=S1 output 11
state=1;
output[i*2]=1;
output[i*2+1]=1;
}
break;
case 1: // if state = S1 '10'
if(input[i] == 0){ // input 0 state=S2 output 10
state=2;
output[i*2]=1;
output[i*2+1]=0;
} else if(input[i] == 1) { // input bit 1 state=S3 output 01
state=3;
output[i*2]=0;
output[i*2+1]=1;
}
break;
case 2: // if state = S2 '01'
if(input[i] == 0){ // input 0 state=S0 output 11
state=0;
output[i*2]=1;
output[i*2+1]=1;
} else if(input[i] == 1) { // input 1 state=S1 output 00
state=1;
output[i*2]=0;
output[i*2+1]=0;
}
break;
case 3: // if state = S3 '11'
if(input[i] == 0){ // input 0 state=S2 output 01
state=2;
output[i*2]=0;
output[i*2+1]=1;
} else if(input[i] == 1) { // input bit 1 state=S3 output 10
state=3;
output[i*2]=1;
output[i*2+1]=0;
}
break;
default :
if(DEBUG_FLAG>3)printf("I can't verify the output! \n");
}
}
}
//Viterbi decoder using Traceback method (5,7), (2,1,2), K=3
void viterbi_decoding(int* input, int* output,int DATA_LEN)
{
int i,j;
int final_state=0;
int metric[NUM_OF_STATES*2];
int s_path_memory[NUM_OF_STATES][DATA_LEN_IN]={0}; //survival path memory
int path_metric[NUM_OF_STATES][DATA_LEN_IN+1] = {{0},{10},{10},{10}}; //start the register from 00
int mar=0;
for(i=0;i<DATA_LEN;i++)
{
for(j=0;j<NUM_OF_STATES;j++)
{
metric[j*2] = branch_metric(j,0,input[i*2],input[i*2+1]);
metric[j*2+1] = branch_metric(j,1,input[i*2],input[i*2+1]);
}
acs(metric,s_path_memory,path_metric,&mar); //choose one branch for path
}
//Output Path
if(DEBUG_FLAG>3)puts("Survival path memory...");
for(j=0;j<NUM_OF_STATES;j++)
{
for(i=0;i<DATA_LEN;i++)
{
if(DEBUG_FLAG>3)printf("%3d",s_path_memory[j][i]);
}
if(DEBUG_FLAG>3)puts("");
}
if(DEBUG_FLAG>3)puts("path metric...");
for(j=0;j<NUM_OF_STATES;j++)
{
for(i=0;i<DATA_LEN+1;i++)
{
if(DEBUG_FLAG>3)printf("%3d",path_metric[j][i]);
}
if(DEBUG_FLAG>3)puts("");
}
final_state = 0;
for(i=1;i<3;i++)
{
if(path_metric[i][DATA_LEN]<path_metric[final_state][DATA_LEN])
final_state = i;
}
trace_back(final_state,s_path_memory,output,DATA_LEN);
}
//BMU-Branch Metric Unit(M3+M2+M1 M3+M1)
int branch_metric(int state,int branch,int data1,int data0)
{
int metric_cal;
//state :
//0 = 00 //M3M2M1 M3=input M2M1 register
//1 = 10
//2 = 01
//3 = 11
//branch :
//0 = upper
//1 = lower
switch(state)
{
case 0: // state = 00
if(branch == 0){ // upper branch
//next = "00";
//value = 00;
metric_cal = (data1 ^ 0) + (data0 ^ 0);
} else if(branch == 1){ // lower branch
//next = "10";
//value = 11;
metric_cal = (data1 ^ 1) + (data0 ^ 1);
}
break;
case 1: // state = 10
if(branch == 0){ // upper branch
//next = "01";
//value = 10;
metric_cal = (data1 ^ 1) + (data0 ^ 0);
} else if(branch == 1){
//next = "11";
//value = 01;
metric_cal = (data1 ^ 0) + (data0 ^ 1);
}
break;
case 2: // state = 01
if(branch == 0){ // upper branch
//next = "00";
//value = 11;
metric_cal = (data1 ^ 1) + (data0 ^ 1);
} else if(branch == 1){
//next = "10";
//value = 00;
metric_cal = (data1 ^ 0) + (data0 ^ 0);
}
break;
case 3: // state = 11
if(branch == 0){ // upper branch
//next = "01";
//value = 01;
metric_cal = (data1 ^ 0) + (data0 ^ 1);
} else if(branch == 1){
//next = "11";
//value = 10;
metric_cal = (data1 ^ 1) + (data0 ^ 0);
}
break;
default:
if(DEBUG_FLAG>3)printf("No such state !!\n");
exit(1);
}
return metric_cal;
}
//ACS-Add Compare Select Unit (part of PMU-Path Metric Unit)
void acs(int* metric,int(*s_path_memory)[DATA_LEN_IN],int(*path_metric)[DATA_LEN_IN+1],int *mar_ptr)
{
int m1,m2,temp_metric[4],i;
// Pres. state = S0, Prev. state = S0 & S2
s_path_memory[0][*mar_ptr] = ((m1=metric[0]+path_metric[0][*mar_ptr]) < (m2=metric[4]+path_metric[2][*mar_ptr])) ? 0 : 1;
temp_metric[0] = m1 < m2 ? m1 : m2;
// Pres. state = S1, Prev. state = S0 & S2
s_path_memory[1][*mar_ptr] = ((m1=metric[1]+path_metric[0][*mar_ptr]) < (m2=metric[5]+path_metric[2][*mar_ptr])) ? 0 : 1;
temp_metric[1] = m1 < m2 ? m1 : m2;
// Pres. state = S2, Prev. state = S2 & S3
s_path_memory[2][*mar_ptr] = ((m1=metric[2]+path_metric[1][*mar_ptr]) < (m2=metric[6]+path_metric[3][*mar_ptr])) ? 0 : 1;
temp_metric[2] = m1 < m2 ? m1 : m2;
// Pres. state = S3, Prev. state = S1 & S3
s_path_memory[3][*mar_ptr] = ((m1=metric[3]+path_metric[1][*mar_ptr]) < (m2=metric[7]+path_metric[3][*mar_ptr])) ? 0 : 1;
temp_metric[3] = m1 < m2 ? m1 : m2;
(*mar_ptr)++;
for(i=0;i<NUM_OF_STATES;i++)
path_metric[i][*mar_ptr] = temp_metric[i];
return;
}
//TBU-Traceback Unit
void trace_back(int state,int(*s_path_memory)[DATA_LEN_IN],int* output,int DATA_LEN)
{
int i,j;
if(DEBUG_FLAG>3)puts("Trace backing...");
// Start from the S0, t=31
j=state;
for(i=DATA_LEN-1;i>=0;i--){
switch(j){
case 0: // if state = S0
if(s_path_memory[j][i] == 0){ // upper path
j=0;
output[i]=0;
} else if(s_path_memory[j][i] == 1) { // lower path
j=2;
output[i]=0;
}
break;
case 1: // if state = S1
if(s_path_memory[j][i] == 0){ // upper path
j=0;
output[i]=1;
} else if(s_path_memory[j][i] == 1) { // lower path
j=2;
output[i]=1;
}
break;
case 2: // if state = S2
if(s_path_memory[j][i] == 0){ // upper path
j=1;
output[i]=0;
} else if(s_path_memory[j][i] == 1) { // lower path
j=3;
output[i]=0;
}
break;
case 3: // if state = S3
if(s_path_memory[j][i] == 0){ // upper path
j=1;
output[i]=1;
} else if(s_path_memory[j][i] == 1) { // lower path
j=3;
output[i]=1;
}
break;
default :
if(DEBUG_FLAG>3)printf("I can't verify the output! \n");
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -