邵瑞,付永庆
哈尔滨工程大学 信息与通信工程学院,黑龙江 哈尔滨 150001
短时傅里叶变换作为一种常用的时-频分析方法,在语音信号、信号识别等方面应用十分广泛[1-3],其基本思想是在傅里叶变换的基础上实现时域的局部化。对于时变信号,短时傅里叶变换采用一个滑动窗截取信号,并且认为窗内的信号是平稳的,对这些信号进行傅里叶变换,可以得到信号在某一时刻的频谱。通常情况下,为了克服窗与窗内数据的关联性,相邻两窗会有所重叠,重叠的长度越长对分析该信号的频谱越准确。本文设置每次滑动的数据长度为滑动窗长度的1/4。
离散序列信号的短时傅里叶变换的定义为
式中:x(m)为待分析的信号;w(n)为分析窗函数;X(ejω)即为待分析信号每个窗的傅里叶变换。离
n散短时傅里叶变换通过滑动窗截取信号,并对该信号进行离散傅里叶变换,提取出信号的局部频域信息。
本设计所采用的开发板为Altera 公司提供的Stratix ii-EP2S180C3,使用的软件环境为Quartus ii 13.0,波形仿真采用了第三方软件Modelsim,开发板的实物图如图1所示。
图1 Stratix ii-EP2S180C3 开发板
本设计充分利用Altera 公司所提供的IP 核,简化了以往设计的过程,设计利用ROM 核存储汉明窗的数据。FIFO 核实现滑动窗。通过使用FFT 核实现傅里叶变换,要根据设计需求进行FFT 核模式的选取,并根据芯片手册进行FFT 核时序的编写。利用这些工具可以很方便地实现滑动短时傅里叶变换的功能,不需要推导复杂的数学公式,相对于文献[4-6]中的复杂数学公式推导更简洁,更容易使用现有工具进行实现。
设计的前提条件是希望判断下一段信号在各个窗内频谱特征,根据频谱特征可以检验信号所含有的频率成分,用于信号解调,设计总体框图如图2 所示。
图2 滑动短时傅里叶变换的FPGA 设计框图
设计中为了避免数据堵塞及丢失,应用了乒乓思想[7],使用了4 个相同的FIFO。4 个FIFO 通过输入数据选择流单元进行控制,使用FIFO_cnt的计数大小判定当前哪个FIFO 写入数据。设计中每次滑动窗更新数据长度为90,则当FIFO1_cnt的大小大于90,此时FIFO2 就要准备进行写入数据;当FIFO2_cnt 的大小大于90,此时FIFO3 就要准备进行写入数据;当FIFO3_cnt 的大小大于90,此时FIFO4 就要准备进行写入数据。至此一个循环下,FIFO 的写使能都打开了。输出数据流选择单元也是通过FIFO_cnt 的数据大小来决定当前哪个FIFO 的数据输出,每个时刻只有一个数据输出,其FIFO 间的滑动图如图3 所示,90、180、270、360 分别代表FIFO 中的4 个地址段。
图3 滑动窗(FIFO)控制设计
汉宁窗的实现采用了ROM 核,存放汉宁窗[8]函数数据。通过MATLAB 生成360 点Hanning 窗函数系数表,由于该数据为浮点数,而本设计中采用定点化运算,将系数表生成mif 文件,作为ROM 的初始化文件。
FIFO 核和ROM 核的使用中设计一个共同的使能,当FIFO 核有数据读出时,ROM 核也会有数据读出,两者同步输出:送入乘法器进行加窗计算,输出数据位宽24 位,送给后端的FFT 模块进行计算,根据FFT 的输出有效信号source_valid 的高低指示,进行判断信号特征,解调信号。
滑动窗使用了异步FIFO[9],FIFO 选择结构如图4 所示。其中FIFO 的大小设置的512,数据位宽是16,读时钟Rdclk 和写时钟Wrclk 的大小相差5 倍,FIFO 的读写使能分别为Rdreq、Wrreq,输出满标志位Wrfull,空标志位Rdempty。
图4 异步FIFO 的结构
设计中需要4 个FIFO,4 个FIFO 轮换输出数据,4 个FIFO 的切换采用了状态机的思想,状态机设计了8 种状态,如图5 所示。当一个状态完成之后,再切换到下一个状态,否则一直处于当前状态。
图5 滑动窗的状态机设计
图6 为滑动窗口的仿真波形,刚开始时,Fifo1_wreq 的电平为高,FIFO1 开始写入数据;当写到第90 个数据时,此时FIFO2 的Fifo2_wreq 置成高电平,FIFO2 开始写入数据;此时State 同时发生跳转;当FIFO2 写数据写到第90 个时,FIFO3的Fifo3_wreq 被置高电平,FIFO3 开始写数据;此时state 在此发生了跳转,数据继续进行写入;当FIFO3 写入数据写到第90 个数据时,此时FIFO1写到了第270 个数据,FIFO4 的Fifo4_wreq 被置成高电平,开始写数据;此时4 个FIFO 的Wreq 都被制成高电平,写入数据。当FIFO1 再写进18 个数据时就要开始读数据,Fifo1_rdreq 变为1,维持读时钟的72 个高电平,360 个数据被写进FIFO1时,同时也读空了,之后开始新的循环。
图6 滑动窗口的仿真波形
当FIFO1 在写进288 个数据时就要开始读数据,Fifo1_rdreq 变为1,维持读时钟的72 个高电平,360 个数据被写进FIFO1 时,同时也读空了,此时FIFO1 的读使能就被关闭;当FIFO2 在写进288 个数据时,FIFO2 就要开始读数据,Fifo2_rdreq变为1,维持读时钟的72 个高电平,360 个数据被写进FIFO2 时,同时也读空了,Fifo2_rdeq 变为0;同理FIFO3、FIFO4。4 个FIFO 轮流输出数据,每次只有一个读使能有效。
图7 为滑动窗模块的仿真波形,可以看到每个窗相邻的将有3/4 的数据是重复的,4 个FIFO轮换输出数据。
图7 滑动窗口控制仿真波形
Hanning 窗使用了ROM[10],ROM 采用Altera公司提供的IP 核,ROM 中的地址线由于只能为2 的整次数幂,取最贴近码元宽度的512 作为该ROM 的地址数,数据位宽为A/DC 的输出数据宽度12,ROM 值在初始化时被赋予了汉宁窗的数据,其结构如图8 所示。
Hanning 窗数据仿真波形为图9,在每个时钟的上升沿数据从ROM 端读出,其数据波形如图中的q 所示。
乘法器的结构如图10 所示。
图8 ROM 窗结构
图9 ROM 读出的数据显示波形
图10 乘法器设计的结构图
输入端数据Dataa、Datab 分别来自于FIFO 输出的数据和ROM 窗内的数据,二者相乘之后的结果为24 位,为信号加过窗的数据,数据送给FFT 模块进行计算。
傅里叶变换[11]部分选择FFT 核[12],FFT 核可以设置FFT 变换的数据长度、输入数据精度、运算中旋转因子数据精度,并提供了4 种运算结构,可以根据板子的运算速度及硬件资源情况进行选择使用。由于数据是实时采集进来的,所以设计结构中选择了流模式。流模式的运算分2 个进程:载入数据及输出数据进程和FFT 变换运算过程,且这2 个进程可以同一时间处理。当FFT 变换启动时,输入数据首先在时钟的控制下输入信号到FFT 核内部的存储器内,当一帧数据载入完成后才开始计算,FFT 变换后的数据在FFT 变换完成后再输出到相应的端口,流模式下的FFT 结构如图11 所示。
图11 流模式下的FFT 结构
流模式的时序接口如表1 所示。流模式的FFT 时序图如图12 所示。从图中可以看出,输入数据是连续的,无论载入数据还是FFT 运算,数据输出都是同时进行的。
表1 FFT 核模块端口介绍
图12 流模式下的FFT 时序
实际应用中,可以根据变换有效数据输出时Source_valid 为高电平期间来确定出现峰值的位置,进而根据位置号推算出信号中包含的信号频率,进行信号的解调等处理。
流模式下的FFT 工作,Modelsim 的波形如图13所示。当有数据输入时Sink_valid 为1;当输入第一个数据时,Sink_sop 为高;当输入最后一个数据时,Sink_eop 电平由低变高,维持一个时钟的高电平。FFT 核计算结束结果输出,Source_valid 拉高。当输出数据第一个值时,Source_sop 被拉高一个时钟的高电平,之后变成低电平;当输出数据最后一个值时,Source_eop被拉高一个时钟的高电平,之后变成低电平。
图13 流模式下的FFT 仿真波形
本文提出了利用Altera 公司提供的现有IP 核进行直接设计实现滑动短时傅里叶变换,从思路到实现上难度都不大,并给出了具体的设计与实现,其采用的方法可以用来其他的相关处理。
1)滑动窗口的实现采用了具有数据先进先出特点的FIFO 作为数据缓存,读写时钟可以不一样,且不用控制地址线,使用操作都很简单。
2)设计中使用了Altera 公司提供的FFT 核直接进行傅里叶变换,只需要根据FFT 手册进行恰当的时序设计,完成自己想要的功能,不需要从原理基础上设计出一个傅里叶变换模块,可以减少研发时间,降低研究成本。