Viterbi译码算法在55系列DSP上的C语言实现
2013-05-15邵凝宁
郭 勇,邵凝宁
(南京北方信息控制集团有限公司产品研发中心,江苏 南京 211153)
0 引言
Viterbi译码算法是针对卷积码的性能最好的译码算法,TI公司的55系列DSP芯片兼容54系列DSP芯片,而且具有功耗更低、运算速率更高等特点,广泛地应用于现代数字通信系统中。目前现有的文献中,对怎样用C语言编程实现Viterbi译码算法论述不多。文献[1—3,8]等用汇编语言编写,可读性较差,文献[4-6]仅仅给出了程序的简化流程图及部分函数的介绍,并没有对Viterbi算法的纠错性能进行详细验证。本文针对常用的(2,1,7)卷积码,设计实现了一种全并行的连续译码的Viterbi算法,硬判决译码,在VC++6.0上开发,再移植到CCS平台上运行,采用文件读写操作的方法进行纠错性能验证。仿真实验结果表明其纠错性能完全达到甚至优于理论上Viterbi译码算法纠错性能的极限。
1 Viterbi译码算法的原理及程序流程
Viterbi译码程序由以下模块组成:文件读、写操作模块,BMU模块,ACS模块,ACS迭代计算模块最小状态值计算模块,回溯模块和ram读写模块等每个模块用相应的函数实现。状态数S=64,回溯深度tblen=42,采用4个数组存储4个ram块的译码结果,分别为Pre_ram[48]用于存储前48时刻的译码结果,ram1[42]、ram2[42]和ram3[42]分别循环存储接下来每42时刻的译码结果,实现连续译码。N为进入(2,1,7)编码器的比特数。
1.1 头文件定义
#include <stdio.h>
#define uint unsigned int
#define N 20000
#define N1 4
#define N2 64
#define N3 42
#define N4 48
//函数申明
extern void File_Read(uint y0[],uint y1[]);
extern void Bmu(uint y0,uint y1,uint b[]);
extern void ACS(uint SM1,uint BM1,uint SM2,uint BM2,uint data[]);
extern void ACS_diedai(uint y0,uint y1,uint ACS_SM[],uint xingcun[]);
┋
extern void State_Huisu(uint Min_State,uint xingcun[],uint state[]);
extern void ram_Huisu(uint Huisu_State[],uint Xingcun[][N2],uint Yima[]);
extern void File_Write(uint yima[]);
// 输入译码器的y0[N]和y1[N]赋初值
static uint y0[N]={0};
static uint y1[N]={0};
static uint ACS_SM[N2]={0};//用于存储每个时刻ACS运算后S0-S63状态的SM值,初始化全为0;
static uint Xingcun_1[N3][N2];// 用于 ram1 的 42 个时刻幸存路径值的存储;
static uint Yima_1[N3];// 存储ram_1的译码结果
static uint yima[N]={0};// 存储全部的译码结果
为节省篇幅,没有全部列出来。
1.2 Viterbi译码算法程序流程
具体的译码流程如图1所示。
图1 译码算法程序流程图
2 各功能模块的函数设计
2.1 File读操作模块
函数void File_Read(uint y0[N],uint y1[N])完成此功能,y0[N]和y1[N]是输入Viterbi译码器的输入待译码数据。
2.2 BMU模块
函数void Bmu(uint y0,uint y1,uint b[N1])完成此功能,b[4]是一个1行4列的数组,用于返回输入值{y0,y1}与00,01,10,11的汉明距离。实际编程时,用指针p指向b[4]。
2.3 前6个时刻SM值计算模块的设计
函数void Pre_ACS(uint y0,uint y1,uint ACS_SM[N2],uint b[],uint i)完成此功能,ACS_SM[N2]是每一时刻对应的S0-S63的SM值,因为ACS_SM[N2]要保持上一时刻的计算结果,所以数组ACS_SM[N2]为static(静态)数组。i为时刻数,i=0-5。
2.4 ACS模块的设计
函数void ACS(uint SM1,uint BM1,uint SM2 uint BM2,uint data[2]),SM1和SM2是路径度量值,BM1和BM2是分支度量值。data[2]是一个1行2列的数组,这里设定,如果SM1+BM1≥SM2+BM2,data[0]=SM2+BM2,data[1]=1;如果SM1+BM1<SM2+BM2,data[0]=SM1+BM1,data[1]=0。
2.5 ACS迭代运算模块的设计
函数void ACS_diedai(uint y0,uint y1,uint ACS_SM[N2],uint xingcun[N2])完成此功能,用指针p1和p2分别指向数组ACS_SM[64]和xingcun[64]),用于返回每次计算更新后64个状态的SM值和幸存值,为防止溢出,如果64个状态的SM值都大于8,则所有的SM值都减去8。
2.6 最小值所在状态模块的设计
函数uint Small_State(uint ACS_SM[N2])实现的功能:在输入某时刻63个状态的SM值时,输出最小SM值所在的状态值。该状态值用于回溯计算的状态起始处。
2.7 状态回溯模块的设计
函数void State_Huisu(uint Min_State,uint xingcun[N2],uint state[2])实现的功能:在给出某一状态及某时刻该状态的幸存值计算预译码值和下一时刻的状态。
2.8 ram_Pre回溯模块的设计
函数void Pre_ram_Huisu(uint Huisu_State_pre[N3+1],uint Xingcun_Pre[N3][N2],uint Yima_Pre[N4])完成此功能。该函数实现的功能是对ram_Pre模块通过回溯得到预译码值。预译码值存入数组 Yima_Pre[6]-Yima_Pre[47]中,与实际的译码结果顺序相反。
2.9 前6个时刻状态回溯计算模块
函数void Pre_Start_Huisu(uint Start_State,uint Yima_Pre[N4])完成此功能,Start_State=Huisu_State_pre[0],用这个值计算t=0-5时刻的预译码值,存入Yima_Pre[0]-Yima_Pre[5]。
2.10 ram回溯模块的设计
函数void ram_Huisu(uint Huisu_State[N3+1],uint Xingcun[N3][N2],uint Yima[N3])用于完成此功能。Huisu_State[42+1],是一个1行43列的数组,存放每一回溯时刻的状态值,Xingcun[N3][N2]是一个42行64列的二维数组,存储用于回溯的42个时刻每一时刻的幸存值。Yima[42]用于存放每一时刻的预译码值,该函数可以被ram1,ram2,ram3调用。
2.11 File写操作模块
函数void File_Write(uint yima[N])用于把数组yima[N]写入yima_out.txt文件中,用来与Yuanbianma.txt文件进行误码率计算。
3 纠错性能测试
对设计的Viterbi译码器C程序纠错性能的测试,采用的方法见文献[7]:进入(2,1,7)编码器的比特数N=20000个,可动态更改。同时把数据写入到Yuanbianma.txt文档中保存。编码后比特数为2*N=40000个,再在Matlab中对编码数据加扰码,然后把有扰码的数据写入到y0.txt文档和y1.txt文档中。C程序读入数据到数组y0[N]和y1[N]。
图2 不同错误形式下BER性能比较曲线图
图3 不同SNR下BER性能比较曲线图
程序运行完成后,译码数组yima[N]的值写入到yima_out.txt文件中。最后把yima_out.txt中的数据导入到Matlab中,计算误比特率。误码形式是以100个比特为一组,编码后每100个比特随机错5位、6位、7位、8位和9位等,还有一种错误形式是对编码数据加高斯白噪声,比较不同信噪比(SNR)条件下的误比特率(BER)。
由图2和图3的曲线可以看出,本文用C语言设计的Viterbi译码器程序,其纠错性能不仅完全达到理论上vitdec()函数纠错性能的极限,而且其纠错性能甚至优于理论算法的纠错性能。
4 结束语
针对卷积码的Viterbi译码算法,本文用C语言进行了各功能函数的设计,给出了完整的程序流程图,并采用大容量编译码数据对Viterbi译码程序进行纠错性能的测试。仿真实验结果表明,本文设计的Viterbi译码程序完全达到甚至优于Viterbi理论算法的纠错性能。采用C语言设计,平台移植性好,程序可读性好。因此,本文设计的Viterbi译码程序具有较好的实际应用价值。
[1]吴莉莉.刘益成.用TMS320C54X实现Viterbi译码器[J].单片机与嵌入式系统应用,2004,4(4):19-21.
[2]董鹏,张锁熊,田迎举.数字卫星通信中的Viterbi算法及DSP实现[J].现代电子技术,2003,2(5):31-33.
[3]吕圣洁,李小文,张传达.适用于TD-SCDMA系统的Viterbi译码及其DSP实现[J].微计算机信息,2008,24(4):166-168.
[4]孙延鹏,赵雪莹,博海玲.基于DSP的Viterbi译码器的实现[J].沈阳航空工业学报,2004,21(4):82-84.
[5]刘少阳,邹永.(2,1,7)卷积编码及其维特比译码算法的软件实现[J].信息与电子工程,2006,4(6):467-469.
[6]赵冰.卷积编码及基于DSP的Viterbi译码器设计[J].信息与控制,2002,31(5):473-476.
[7]郭勇,陈艳玲.Viterbi-IP核纠错性能的验证[J].电讯技术,2012,10(52):1702-1705.