一、STFT基本介绍
本专栏之前的三篇文章中,详细介绍了如何使用Chisel快速搭建FFT流水线电路。同时在这几篇文章中,所提到的对音频信号进行预处理的过程,其中有一步是对数据进行短时傅里叶变换(short-time Fourier transform,STFT)。因此,我们可以考虑在该FFT电路上对其进行拓展开发,以实现STFT功能。
STFT思想是:选择一个时频局部化的窗函数,假定分析窗函数g(t)在一个短时间间隔内是平稳(伪平稳)的,移动窗函数,使f(t)g(t)在不同的有限时间宽度内是平稳信号,从而计算出各个不同时刻的功率谱。短时傅里叶变换使用一个固定的窗函数,窗函数一旦确定了以后,其形状就不再发生改变,短时傅里叶变换的分辨率也就确定了。如果要改变分辨率,则需要重新选择窗函数。
在本实验中,结合KWS-SoC开发中实际的应用。我们选择对单帧音频数据进行短时傅里叶变换,其中单帧为320个数据点,其中数据点数是可以配置的,只需要用户在生成IP核的时候设置对应的参数,并且重新生成窗函数对应的权值点即可。
在之前的两篇文章([1](格斯:用Chisel快速搭建FFT流水线电路),[2](格斯:用Chisel快速搭建FFT流水线电路(续篇)—— 开源工程和使用教程))中,我们对如何使用Chisel快速搭建FFT流水线电路的基本方法进行了简要介绍,且在开源地址
https://github.com/IA-C-Lab-Fudan/Chisel-FFT
对相应的代码和工程进行了开源。
本实验最终的工程同样开源于以上工程的STFT分支中。
二、设计流程
简单分析下音频预处理流程中的HLS源码,我们可以将STFT划分成以下三个大步骤,如图所示:
为了提高数据处理的效率,我们把三个模块划分为三级流水线,模块之间通过valid/ready进行握手传输。
需要注意的是,在原FFT工程中,FFT顶层模块的输入握手信号是突发式握手的,也就是说data_in每次握手一次,需要连续传输FFT_LENGTH个信号。因此,我们需要对第一级Hanning模块的输出握手信号进行修订,使其满足FFT突发握手的需求。