⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 channel_coding.c

📁 应用于WIMAX标准的下的信道编码和解码
💻 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 + -