FPGA使用HLS实现快速傅里叶变换 FFT

FFT 是离散傅立叶变换的快速算法,可以将一个信号变换到频域。 N 个采样点,经过 FFT 之后,就可以得到 N 个复数结果。为了方便进行 FFT 运算,通常 N 取 2 的整数次方。这里我们设定最大为 1024,即 2 的 10 次方。

假设采样频率为 Fs,信号频率 F,采样点数为 N。那么 FFT 之后结果就是一个为 N 点的复数。每一个点就对应着一个频率点,即 Fn=(n-1)*Fs/N。这个点的模值,就是该频率值下的幅度特性。

假设 FFT 之后某点 n 用复数 a+bi 表示,那么这个复数的模就是 An= √a ∗ a + b ∗ b,相位就是 Pn=atan2(b,a)。根据以上的结果,就可以计算出 n 点(n≠1,且 n<=N/2)对应的信号的表达式为: An/(N/2)*cos(2*pi*Fn*t+Pn),即 2*An/N*cos(2*pi*Fn*t+Pn)。对于 n=1 点的信号,是直流分量,幅度即为 A1/N。由于 FFT 结果的对称性,通常我们只使用前半部分的结果,即小于采样频率一半的结果。

模块首先使用指定的内存数据 pSrc 初始化 xn 数组,接下来调用 fft 完成变换,结果存放在数组 xk 中,最后,我们计算模值并拷贝至 pDst。这里模值因为 scale 关系,需要乖 2048。


void getfft(int nfft, unsigned short *pSrc, unsigned short *pDst)
{
#pragma HLS INTERFACE s_axilite port=nfft
#pragma HLS INTERFACE m_axi port=pSrc offset=slave
#pragma HLS INTERFACE m_axi port=pDst offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS dataflow
config_t fft_config;
status_t fft_status;
cmpxDataIn xn[FFT_LENGTH];
cmpxDataOut xk[FFT_LENGTH];
fft_config.setDir(0);
fft_config.setSch(0x2AB);
fft_config.setNfft(nfft);
access_src(pSrc, xn, 1<<nfft);
hls::fft<config1>(xn, xk, &fft_status, &fft_config);
access_dst(pDst, xk, 1<<nfft);
}

这里, setSch(0x2AB) 是设置 scale,即蝶形算法的每一级右移的位数 [2 2 2 2 3]。这样确保最后的结果也是 16 位的。这里 scale 对应的十进制值是 2^(2+2+2+2+3)=2048。

setNfft 用来设置采样数据长度,这里定义 10,即 2 的 10 次方,表示 1024 个采样点, setDir用来设置正逆变换。

虚框中为生成的三个波形叠加波形,虚框下面为 FFT 后结果,这里直流分量没有显示。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值