摘要:到目前为止,我们已经描述了DSP处理器的物理架构,解释了DSP如何比传统电路提供一些优势,并检查了数字滤波,展示了DSP的可编程特性如何使其适合这种算法。现在我们看一下在硬件平台ADSP-2181EZ-Kitlitetm上实现有限脉冲响应(FIR)滤波器算法的过程(在第2部分中简要介绍,用ADSP-2100系列汇编代码实现)。该实现被扩展为处理数据I/O问题。
到目前为止,我们已经描述了DSP处理器的物理架构,解释了DSP如何比传统电路提供一些优势,并检查了数字滤波,展示了DSP的可编程特性如何使其适合这种算法。现在我们看一下在硬件平台ADSP-2181EZ-Kitlitetm上实现有限脉冲响应(FIR)滤波器算法的过程(在第2部分中简要介绍,用ADSP-2100系列汇编代码实现)。该实现被扩展为处理数据I/O问题。
DSP的许多架构特性,例如执行零开销循环的能力,以及在单个处理器周期中获取两个数据值的能力,将有助于实现该滤波器。简要回顾一下,FIR滤波器是一种全零滤波器,它是通过将输入数据点序列与滤波器系数进行卷积来计算的。其控制方程和直接形式表示如图1所示。
在这个结构中,每个“z(-1)”方框表示输入数据在z变换表示法中的单个增量。将每个连续延迟的样本乘以相应的系数值h(m),将结果加在一起,生成一个单独的值,表示第n个输入样本对应的输出。延迟元件或滤波器抽头的数量及其系数值决定了滤波器的性能。
滤波器结构给出了在DSP上计算实现该算法所需的物理元素。对于计算本身,每个输出样本需要若干次相乘累加操作,这些操作等于过滤器的长度。
输入数据的延迟线和系数值列表需要在DSP中预留内存区域来存储数据值和系数。DSP的增强型哈佛架构允许程序员将数据存储在程序内存和数据内存中,从而在DSP的内部SRAM的每个周期中执行两次同步内存访问。数据存储器保存传入的样本,程序存储器存储系数值,数据值和系数值都可以在一个计算周期内获取。
这种DSP体系结构有利于使用循环缓冲的程序(在第2部分和本文后面的部分中进行了简要讨论)。这意味着地址指针只需要在程序开始时初始化,而循环缓冲机制确保指针不会离开其分配的内存缓冲区的边界——这一功能在FIR滤波器代码中广泛用于输入延迟线和系数。一旦确定了程序的要素,下一步就是开发DSP源代码来实现算法。
ADSP-2100系列的软件开发流程包括以下几个步骤:体系结构描述、源代码生成、软件验证(调试)和硬件实现。图2显示了一个典型的开发周期。
体系结构描述:首先,用户创建运行算法的硬件系统的软件描述。系统描述文件包括系统中的所有可用内存和任何内存映射的外部外设。下面是使用ADSP-2181EZ-KitLite的此过程示例。
源代码生成:从理论到实践,这一步——将算法思想转化为在dsp上运行的代码——通常是整个过程中最耗时的一步。有几种方法可以生成源代码。有些程序员更喜欢用C等高级语言编写算法;其他人更喜欢使用处理器的本机汇编语言。对于程序员来说,用C语言实现可能更快,但是编译后的DSP代码由于没有充分利用处理器的架构而缺乏效率。
软件验证(“调试”):此阶段使用称为模拟器的软件工具测试代码生成的结果,以检查程序的逻辑流程并验证算法是否按预期执行。模拟器是DSP处理器的一个模型,它a)提供对所有存储器位置和处理器寄存器的可见性,b)允许用户连续运行DSP代码或一次运行一条指令,c)可以模拟向处理器提供数据的外部设备。
硬件实现:这里的代码是在真正的DSP上运行的,通常分为几个阶段:a)在评估平台(如EZ-KitLite)上试用;b)电路仿真,c)生产ROM生成。试用提供了程序运行的快速进行/不进行的决定;该技术是本文中使用的实现方法。电路仿真监控系统中的软件调试,其中EZ-ICE等工具控制目标平台上的处理器操作。在所有调试完成后,可以生成包含最终代码的引导ROM;它作为最终的生产实现。
我们的开发周期示例通过该过程,使用ADSP-2181EZ-KitLite(开发包ads-21xx-EZLITE)作为滤波器算法的目标硬件。EZ-KitLite是一个低成本的演示和开发平台,由一个33mhz的ADSP-2181处理器、一个AD1847立体声音频编解码器和一个插入式EPROM组成,其中包含用于通过RS-232连接将长新算法下载到DSP的监控代码(图3)。
可用的系统资源信息记录在系统描述文件中,供ADSP-2100系列开发工具使用。系统描述文件的扩展名为.sys。下面的列表显示了一个系统描述文件[EZKIT_LT]。系统:
系统的EZ_LITE;/*给这个系统一个名字*/
.adsp2181;/*指定处理器*/
.mmap0;/*指定系统启动,*/;
/*PM位置0在内存中*/
.seg/PM/RAM/ABS=0/代码/数据int_pm[16384];
.seg/DM/RAM/ABS=0int_dm[16352];
.endsys;/*结束描述*/
本系列的第2部分[对话31-2,第14页,图6]介绍了FIR滤波器的小汇编代码清单。这里,该代码被增强为包含一些EZ-Kitlite特定的功能,特别是编解码器初始化和数据I/O。过滤器算法的核心元素(乘法累加、对数据和系数使用循环缓冲区进行数据寻址以及依赖于零开销循环的效率)没有改变。
输入数据将使用板载AD1847编解码器进行采样,该编解码器具有可编程采样率、输入增益、输出衰减、输入选择和输入混音。它的可编程特性使系统具有灵活性,但也增加了对DSP系统进行初始化编程的任务。
对于本例,编解码器的一系列控制字(在清单第一部分的程序开始处定义)将初始化它为8khz采样率,每个输入通道具有中等增益值。由于AD1847是可编程的,用户通常会重用接口和初始化代码段,仅为不同的应用程序更改特定的寄存器值。这个例子将特定的过滤器段添加到EZ-KitLite软件中现有的代码段中。
使用EZ-KitLite软件中的I/Oshell程序,我们只需要涉及标记为“input_samples”的代码部分。当从编解码器接收到准备处理的新数据时,访问这部分代码。如果只需要正确的通道数据,我们需要读取位于位置rx_buf+2的数据内存中的数据,并将其放入数据寄存器中,以便输入到过滤器程序中。
来自编解码器的数据需要使用ADSP-2181的循环缓冲能力,通过输入延迟线馈送到滤波器算法中。输入延迟线的长度由滤波器所用系数的数目决定。因为数据缓冲区是循环的,所以缓冲区中最老的数据值将是指针在最后一次过滤器访问后所指向的位置(图4)。同样地,每次通过过滤器总是以相同的顺序访问的系数被放置在程序内存中的一个循环缓冲区中。
ADSP-2181的MAC将结果存储在一个40位寄存器中(32位用于2个16位字的乘积,8位用于允许总和扩展而不会溢出)。这允许中间过滤器值根据需要增长和缩小,而不会损坏数据。所使用的代码段是通用的(即,可以用于任何长度过滤器);所以MAC的额外输出位允许运行带有未知数据的任意过滤器,而不用担心丢失数据。
为了实现FIR滤波器,对每个数据点的滤波器的所有轻击重复乘法/累加操作。为了做到这一点(并为下一个数据点做好准备),MAC指令以循环的形式编写。ADSP-21xx的零开销循环能力允许MAC指令重复指定数量的计数,而无需编程干预。计数器设置为轻击数减一,循环机制自动减少每个循环操作的计数器。将循环计数器设置为“taps-1”确保数据指针在执行完成后在正确的位置结束,并允许最后的MAC操作包括舍入。由于AD1847是一个16位编解码器,带舍入的MAC提供了一个统计无偏的结果,舍入到最接近的16位值。这个最终结果被写入编解码器。
当对每个输入数据样本执行过滤器代码时,MAC循环的输出将被写入输出数据缓冲区tx_buf。虽然这个程序只处理单通道输入数据,但是通过写入内存缓冲区地址tx_buf+1和tx_buf+2,结果将被写入两个通道。
EZ-KitLite提供的基于windows的监控软件可以将可执行文件加载到EZ-KitLite板上的ADSP-2181中。这是通过选择“下载用户程序并运行”(图5)下拉“Lolong”菜单完成的。这将下载滤波器程序到ADSP-2181并开始程序执行。
本文的目标是概述从算法描述到可以在硬件开发平台上运行的DSP可执行程序的步骤。介绍的问题包括软件开发流程、体系结构描述、源代码生成、数据I/O和EZ-KitLite硬件平台。