一个 FFT 可以分解成多个并行通道吗?

信息处理 fft
2022-01-27 17:25:52

假设我有一个以特定频率(即 1 GHz)采样的数据流。我现在想对该数据流执行 FFT,但由于我拥有的硬件被限制为 250 MHz 的最大时钟频率,因此数据以 4 个数据包的形式到达。换句话说,每个时钟周期有 4 个不同的样本到达。是否可以使用 4 个并行 FFT 来完成此操作?

现在我知道没有什么能阻止我这样做,所以我的问题是我是否会失去任何频率精度?每个 FFT 仅在 250 MHz 上运行,所以我担心我可以根据香农定理安全测量的最高频率仅为 125 MHz,而 500 MHz

2个回答

因此,将大型 DFT 分解为较小的 DFT,其中一些计算是多余的,这正是Cooley-Tukey 算法使用的技巧。所以,你的 FFT 已经在内部这样做了,我怀疑你会写出更好的 FFT。4 个并行 FFT 是不够的 - 之后您需要一个蝶形结构来再次组合它们。(您对四个 250 MHz 流¹的考虑发现您的原始信号具有 1 GHz 的带宽,因此如果您只对每四个样本进行一次 FFT,就会产生混叠;蝴蝶实际上是一种取消的数学方法使用来自其他三个 FFT 的信息进行混叠。)

您可能想阅读关于Cooley-Tukey 算法的维基百科页面的 Radix-2 部分。


¹您考虑的问题是您的奈奎斯特带宽 == 采样率对于所有实际目的,因为 DFT 处理复杂信号,而不仅仅是真实信号。

我已经组装了一个显示@Marcus 解决方案的小python 脚本。我想分享这个作为概念证明,说明这对于遇到与我相同的问题的任何人是如何工作的。

我需要使用四个独立通道的原因是因为我正在开发一个包含 FFT 的 FPGA 实现。我无法选择并行处理数据的实现,但我得到的数据总是以 4 个数据包的形式到达。

对此方法的任何改进表示赞赏

from numpy.fft import fft, fftshift
import numpy as np
import matplotlib.pyplot as plt

size = 2048
n = np.arange(size)
x = np.e ** (-2j * np.pi * 0.3 * n) # some arbitrary data
N = 4 # the amount of channels
x_i = [x[idx::N] for idx in range(N)] # The data, rearranged for the channels

def bf_2(even, odd):
    """
    2-point butterfly implementation
    """
    points = len(even) + len(odd)
    def w(k):
        return np.e ** (-2j * np.pi * k / points)
    twiddles = w(np.arange(points/2))
    odd = odd * twiddles
    even_ret = even + odd
    odd_ret = even - odd
    return np.concatenate([even_ret, odd_ret])

def bf_4(x0, x1, x2, x3):
    """
    four-point butterfly implementation
    """
    res_1 = bf_2(x0, x2) # equivalent to bit-reverse ordering
    res_2 = bf_2(x1, x3) # equivalent to bit-reverse ordering
    return bf_2(res_1, res_2)

# Compute four separate FFT's
A_i = map(fft, x_i)

# And re-assemble them using the butterfly-structure
x_restored = bf_4(*A_i)

mag = np.abs(x_restored)
f = np.linspace(-0.5, 0.5, len(mag))
plt.plot(f, fftshift(mag))
plt.show()