MPEG-4是一种开放性标准,其中许多部分都没有规定,可以加入一些新的算法,因此采用通用DSP能够随时更新算法、优化算法、使得编码效率更高。由于MPEG-4编码算法复杂,需要存储的数据量大,无论是存储空间分配、数据传输还是运算速度对DSP来说都是挑战。本文介绍了基于C6000系列DSP的MPEG-4视频编码卡的软硬件实现。利用DSP的VLIW和流水线结构设计程序可以使MPEG-4编码效率大大提高。
1DSP特性介绍
由于算法的复杂性及数据量的日益增大,单靠串行结构的处理器完成数据处理工作已经越来越不可行,因此出现了并行结构的CPU以完成这一新的任务。现今最著名的两种并行体系结构是超长指令字VLIW(Very Long Instruction Word)结构和超标量体系结构。由于超标量体系结构CPU硬件极其复杂,指令动态调度将导致时间的不确定性,所以DSP很少使用这种结构。而一般使用超长指令字(VLIW)结构,这种长指令通常包括多个彼此独立的同步操作。
C6000系列DSP是TI公司生产的高档DSP。这一系列DSP都是基于VelociTIT构架的VLIW DSP,它在每个周期可以执行八条32bit的指令,具有高达200MHz的COY,从而使得其运算能力达到1600MIPS(200MHz×8条指令=1600MIPS)。这些性能都确立了它在高端多媒体应用中的地位。
DSP的CPU结构如图1所示,它具有两个通道,每个通道具有4个功能单元(1个乘法器和3个算术逻辑单元),16个32位通用寄存器,每个通道的功能单元可以随意访问本通道的寄存器。CPU还有两个交叉单元,通过它们,一个通道的功能单元可以访问另一个通道的寄存器。另外CPU还具有256bit宽的数据和程序通道,可以使程序存储器在每个时钟周期提供8条并行执行指令。这种CPU结构是DSP具有VLIW结构的最基本条件。此系列DSP的存储空间映射为内部存储器、内部外设及扩展存储器。其中内部存储器由64KB内部程序存储器和数据存储器构成,内部程序存储器可以映射到CPU地址空间或者作为Cache操作。内部和外部数据存储器均可通过CPU、DMA或HPI(HostPort Interface)方式访问,HPI接口使上位机可以访问DSP的存储空间。
2 MPEG-4编码卡的硬件设计
MPEG-4编码卡包括几部分:视频采集、视频的MPEG-4编码、整个系统的CPLD控制、PC机与DSP的通信等模块,其结构框图如图2所示。
2.1视频采集
视频采集部分主要完成模拟视频到数字视频的转换,包括一片视频采集芯片和一片小的CPLD。CPLD的作用是控制视频采集芯片,将采得的数据从8位或16位转化为32位,并且使数据按照Y、U、V分开的方式排列。这样相当于对采集到的数据进行了一次预处理,以便于视频编码使用。另外,CPLD将32位宽的数据输出给32位的FIFO。用32位的FIFO以及将视频数据转换为32位,可以使DSP读取视频数据时32位的数据总线没有空闲,从而提高DSP读取视频数据的效率;这里使用FIFO是为了减少DSP读取数据的时间、降低高速设备和低速设备的不匹配。每次FIFO半满时,CPLD会给DSP发送中断信号,并且在中断处理程序中使用DMA方式读取视频数据;如果不使用FIFO,DSP会频繁中断,从而花费大量时间在入栈、出栈以及寄存器的设置上。
2.2 视频编码
DSP读入视频数据后进行先期处理,如将YUV格式转为RGB格式等;然后进行MPEG-4视频编码。在这一过程中,数据访问通常要占用50%的时间,算术运算要占用30%的时间,控制要占用20%的时间。因为需要进行运动估计和运动补偿,在数据存储器中通常保存一帧I(原始帧)帧图像和至少一帧P(预测帧)帧图像,这些图像占用的空间都比较大,因此一般都放在外部存储器SDRAM里。在编码过程中还要存储DCT系数、运动向量、量化矩阵、可变长编码表、Z形编码表等,由于占用较小的存储空间而且会反复用到,因此把它们放在片内存储器中。
2.3 PC与编码卡通信
PC与编码卡通信可以通过并口、串口、USB口、PCI接口等方式实现。其中PCI接口方式易于PC与编码器高速传输数据,因此本文采用PCI接口。编码后的数据通过DSP的HPI、PCI桥芯片、PCI总线到达PC。PC通过DSP的HPI直接对DSP的存储空间进行访问。HPI有两种工作方式:一种是单数据读写,这种方式每次只能读写一个数据,一般主机对编码参数进行设置,例如设置图像大小、帧率等;另一种是burst方式的数据读写,在这种方式下只需要指定初始访问地址,然后以地址自加的方式访问DSP的存储空间,这种访问方式不需要DSP的CPU参与。图2中CPLD完成PCI桥芯片与DSP之间的访问控制,DSP、PCI的中断控制等功能。
3 MPEG-4编码卡的软件设计
C6000系列DSP提供的编译环境支持C++、C以及汇编语言,用C++设计的程序执行效率较低,一般不用;大多数都采用C语言和汇编语言相结合的方式来完成DSP程序设计。DSP程序设计流程如下:先写出C代码并对其优化,如果不能达到预期的运行效率,则编写汇编代码来提高效率。对于MPEG-4这样复杂的算法,只运用C语言是远远不够的,在本设计里大部分代码都由汇编语言完成。
设计高效的代码,必须充分利用该DSP的VLIW和流水线结构。利用VLIW结构可以在一个时钟周期并行执行八条32位指令;在流水线结构下,一条指令的执行不用等待上一条指令执行结束,例如DSP从内存中读取一个数据需要5个时钟周期,在读取这个数据的同时,DSP可以去执行别的指令,不必等待这条指令执行结束。具有这两种结构的DSP在性能提高的同时,程序设计也变得比较复杂。对于具有VLIW和流水线结构的DSP在设计程序时必须注意以下几个问题:
·每一个指令包可以包括多条操作指令,在C6000系列DSP中每一条指令包括八条32位操作指令;
·可以将两个16位数据或者四个8位数据合并成一个32位数据,以提高存取效率;
·必须静态地知道每条操作指令执行需要的时钟周期,这样才能取得该操作的正确结果;
·这种结构的处理器不能处理动态事件,例如Cache突然消失;
·对于多周期才能完成的指令,在正确计算的基础上,一定要提前执行,以免出现一条指令必须等上一条指令执行结束才能执行的情况。
下面结合C6000系列DSP的指令及其具体资源情况,以MPEG-4中的算法为例说明如何利用这两种结构设计出高效的代码。
3.1 利用流水线结构设计程序
流水线是指指令的处理可分为几个子操作,每个子操作由不同的单元完成。对每个单元来说,每隔一个时钟周期可进入一条新指令,在同一时间内不同单元可以同时处理多条指令。在C6000中B(.unit)lable是一条跳转指令,它的执行周期为7个时钟周期,也就是说,在安排这条指令之后6个时钟周期才能使程序转移到lable处执行,以程序1为例说明如何利用流水线结构设计程序。该程序的执行顺序如下:0000→0004→0008→000C-0010→0014→0008→000C...从程序执行顺序知道,要想在执行完0014处的指令后跳转到LOOP处,就应该在0014的前6个时钟周期处安排这条指令;如果不提前安排好这条指令,而是在0014后放置这条指令,就需要使CPU等待6个时钟周期才能跳到LOOP处,从而使程序运行效率降低。从这个程序的执行顺序可以看出,必须提前知道每一条指令的运行周期数,并提前安排该指令,才能达到减少等待周期、提高程序效率的效果。C6000C6000系列DSP指令集包括许多多时钟周期的指令,如跳转指令、数据访问指令等。MPEG-4编码算法需要频繁地访问大量数据,并且有很多循环,无论是数据访问还是循环都要用到多时钟周期指令。以MPEG-4的DCT算法为例,每一个8×8的块变换需要用16次的跳转指令和256次数据访问指令,由此可见流水线在MPEG-4程序优化中所起的作用。
程序1利用流水线特性设计程序
0000 B .S1 LOOP
0004 ADD .L1 A1 A2 A3
0008LOOP MPY .M1X A3 B4 A4
000C MPY .M1 A3 A6 A5
0010 MPY .M1 A6 A7 A8
0014 SHR .S1 A4 15 A4
0018 ADD .D1 A4 A6 A4
3.2 利用VLIW结构设计程序
利用VLIW结构设计程序可以充分利用DSP多个功能单元并行工作的特性。DSP的每一个通道都有四个功能单元(L、S、M、D),每个功能单元负责完成一定的逻辑或者算术运算,另外A、B两个通道的互访可以通过交叉单元1x、2x完成。程序2中,在一个时钟周期内并行执行八条指令,使用了所有的功能单元S2、S1、L1、M2、L2、M1、D1、D2,同时使用了所有的交叉单元1x、2x,已经达到极限。但是这种并行指令的使用也有一定的限制,其最根本的要求就是不能引起资源冲突,例如:
·不能用同一个功能单元;
·不能对同一通道的寄存器进行两次long型写操作;
·不能对同一通道的寄存器同时进行long型读操作和存储操作;
·读同一寄存器不能超过4次;
·在同一个时钟周期不能有两个指令写入同一寄存器,这不是说向同一寄存器写的两条指令不能放在同一个并行指令包内,而是说两个指令不能在写寄存器的那个时钟周期并存。
程序2利用VLIW结构设计程序
SUB .S2X B0 A0 B0
|| ADD .S1X A1 B1 A1
|| ADD .L1 A2 A3 A4
|| MPYH .M2 B2 B3 B4
|| ADD .L2 B5 B6 B7
|| MPY .M1 A5 A6 A7
|| LDH .D1 A8 A9
|| LDH .D2 B9 B8
仍然以MPEG-4中的DCT算法为例说明VLIW结构在程序优化中的作用。进行DCT变换的原始数据是short型的,因此可以将两个数据合成一个32位的数据来访问;为了使两个通道并行访问数据和运算,应尽量把要访问的数据平均地分配给不同的通道寄存器;并且通过交叉单元使两个通道相互访问,从而达到很高的并行性,大大提高了编码效率。
MPEG-4编码的其它算法,例如逆DCT、运动估计、运动补偿等算法都包含着大量的循环运算和数据访问。因此利用DSP的VLIW结构和流水线结构优化MPEG-4编码算法就成为一种非常合适的方法。
当然,编写程序时不是将DSP的VLIW结构和流水线结构分开考虑,而是将两者结合起来,在编写每一条指令时都要清楚这条指令的执行周期以及使用的功能单元,这样才能编写出高效的程序。
表1对1-D Chen 8×8 DCT、100点点积和FIR滤波器算法的C语言实现与利用VLIW及流水线结构的汇编代码实现进行比较。从统计数据可以看出,利用DSP结构编写的汇编代码执行效率要比C语言编写的代码执行效率高40倍左右。因此充分利用DSP的VLIW结构和流水线结构设计汇编程序能够使效率大幅度提高。
本文对MPEG-4编码卡进行了设计,主要难点是MPEG-4编码算法的优化,MPEG-4的编码复杂、代码量大。利用C6000系列DSP的VLIW结构和流水线结构设计出了MPEG-4编码算法。实验证明,算法效率得到了大幅度提高。