基于FPGA的高性能数字信号处理器设计与实现
2024-05-25张本
张本
中兴系统技术有限公司,广东深圳,518000
0 引言
在当今数字通信、雷达、图像处理和许多其他领域,对高性能数字信号处理的需求不断增加。为了满足这种需求,研究和设计高性能数字信号处理器变得至关重要[1]。现场可编程门阵列(FPGA)已经成为这些领域中的一种强大工具,因为它提供了灵活性、可编程性和并行性,这些特性使它成为高性能数字信号处理器的理想选择[2]。本研究的目标是设计和实现一种基于FPGA的高性能数字信号处理器,以满足现代通信和信号处理应用的需求。数字信号处理器将通过FPGA上的硬件描述语言(Verilog)进行编程,以执行信号处理任务。本文选用最常用的FFT算法进行详细设计和实现,用以说明FPGA作为数字信号处理器的卓越性能。
1 信号处理器整体结构形式
处理器的系统框图如图1所示。
1.1 控制单元
控制单元是FFT处理器的关键组件[3],它负责管理和协调整个FFT计算流程,确保计算的正确性、时序性和数据访问的准确性。控制器和地址产生单元的有效协同工作是FFT处理器顺利运行的关键。
1.1.1 控制器
控制器是FFT处理器的大脑,它执行以下功能。
(1)启动和停止FFT计算:控制器允许用户启动FFT计算过程,并在需要时停止计算。这确保了计算的控制权在用户手中。
(2)时序管理:控制器负责确保蝶形运算按正确的顺序和时序执行。它发出信号,告诉蝶形运算单元何时进行计算,以保持整个计算的同步性。
(3)控制信号生成:控制器生成用于控制蝶形运算和存储单元的控制信号。这些信号包括读取和写入操作的启动、停止、重置等。
(4)状态管理:控制器维护FFT计算的当前状态,以确保正确的计算流程。它可以管理多级蝶形图的不同阶段,并确保它们按照正确的顺序执行。
控制器的关键任务是协调所有组件,以确保FFT计算按照正确的顺序和时序执行,以生成正确的频谱结果。
1.1.2 地址产生单元
地址产生单元的主要作用是确保数据正确地进出存储单元,以支持FFT计算进行。
(1)地址计算:地址产生单元计算出需要读取或写入存储单元的地址,以确保正确的数据访问。这通常涉及数据的分组和重新排列,以匹配FFT计算的顺序。
(2)地址同步:地址产生单元与控制器进行协同工作,以确保生成的地址与FFT计算的状态同步。这防止了地址与数据的不匹配。
(3)地址传输:地址产生单元将生成的地址传输给存储单元,以触发正确的数据读取或写入操作。
1.2 蝶形运算单元
蝶形运算器和旋转因子计算单元的协同工作使FFT处理器能够高效地进行傅里叶变换。蝶形运算器执行核心运算,而旋转因子计算单元确保这些运算在频率域上正确执行。这些部分的优化对于FFT处理器的性能至关重要。
1.2.1 蝶形运算器
蝶形运算器是FFT处理器中的核心组件,它在傅里叶变换中执行关键的运算。蝶形运算器接收一对复数输入数据点,执行复数乘法和加法运算,然后将结果存储回存储单元。这一过程是FFT计算的核心步骤,具有高性能和高吞吐量。在每个时钟周期内,蝶形运算器执行以下操作。
(1)输入数据接收:从存储单元中获取两个复数输入数据点,通常是一个复数对,这两个数据点表示不同的频域样本。
(2)复数乘法:将这两个输入数据点相乘,通常使用乘法器进行计算。这个操作计算出乘积的幅度和相位信息。
(3)复数加法:接下来,将乘法的结果进行复数加法运算,以获得蝶形运算的输出数据点。
(4)结果存储:最终,计算得到的输出数据点被存储回存储单元,以供后续的计算或输出使用。
这个过程在FFT计算中不断重复,以完成信号处理的任务。蝶形运算器的设计需要高效的硬件实现,以确保FFT处理器能够快速且准确地完成傅里叶变换。
1.2.2 旋转因子计算单元
旋转因子计算单元负责生成用于蝶形运算的旋转因子。这些因子用于复数乘法操作,确保正确的频率域转换。
旋转因子计算单元根据FFT计算的当前阶段和频率要求,生成旋转因子。这通常涉及预先计算和存储一组旋转因子,以供FFT计算使用。这些因子通常在FFT处理器初始化时计算,并在需要时从存储中获取。生成旋转因子的精确性和性能对FFT计算的准确性和速度至关重要。如果旋转因子的计算出现错误,可能导致频谱分析的结果不准确。
生成的旋转因子与蝶形运算器的输入数据相乘,以实现频率域的旋转。这是通过复数乘法操作来实现的,确保了FFT计算中正确的频域变换。旋转因子的应用使蝶形运算器能够将输入数据点正确旋转到适当的频率位置,这是傅里叶变换的核心步骤。
1.3 存储单元
存储单元在FFT处理器中用于暂时保存数据,以便进行傅里叶变换的各个阶段。其设计和性能对FFT计算的速度和准确性具有重要影响,因此,需要根据具体应用的需求进行合适的优化和配置。
1.3.1 输入数据存储
存储单元首先用于存储从外部输入源传入的原始数据。这些输入数据通常是时域的样本,即待处理的信号。数据存储的方式通常取决于FFT处理器的设计,可以是一个连续的缓冲区或分块存储。
1.3.2 中间结果存储
在FFT计算中,蝶形运算需要将中间结果存储在存储单元中,以便进行下一级的计算。中间结果是蝶形运算的输出,通常是频域的部分计算结果。存储单元允许数据在各个蝶形运算之间流动,并保持正确的顺序。
1.3.3 最终输出存储
存储单元还用于存储最终的FFT输出数据,即频域中的信号分量。这些数据表示输入信号在频域中的频率分量。最终输出数据通常需要进一步分析、处理或传输给其他系统。
1.3.4 随机存储器和缓冲区
存储单元可以采用不同的物理实现方式,最常见的是使用随机存储器。随机存储器可以读取和写入数据,具有快速的访问速度。此外,存储单元还可以包括用于存储数据的缓冲区,这些缓冲区可以用于提高数据流动的效率,确保数据可以及时传递给蝶形运算单元。
1.3.5 地址管理
存储单元需要能够有效地管理数据的读取和写入,以确保数据能够在正确的时间和顺序下传输。地址产生单元通常与存储单元协同工作,生成用于数据访问的地址。
1.3.6 数据流动
数据在存储单元内部的流动是整个FFT计算的关键。输入数据被读取,然后经过蝶形运算后的中间结果被存储,最终的FFT输出数据也被存储。这个流动过程需要高效的数据传输和存储管理,以确保计算的正确性和效率。
1.4 总线模块
总线模块在处理器中是至关重要的组件,它负责数据和控制信号的传输,以确保各个组件能够正确地访问和交换数据。
1.4.1 地址总线
地址总线用于传输地址信息,以指定要访问的存储单元或其他组件的位置。地址总线的位数取决于FFT处理器的设计,通常与存储单元的地址位数相匹配。控制单元使用地址总线来发出读取或写入操作的地址,以确保正确的数据访问。
1.4.2 数据总线
数据总线的宽度通常与处理器的数据宽度相关。数据总线的功能包括在存储单元和蝶形运算单元之间传输数据,以及将最终的FFT输出数据传送给外部系统或存储设备。输入数据从外部传入FFT处理器,通过数据总线传输到存储单元。控制单元通过地址总线指定要写入的存储单元的位置。中间结果由蝶形运算单元计算并存储在存储单元中,然后通过数据总线传输到下一级的计算。最终的FFT输出数据也通过数据总线传送出来,以供后续处理或输出。
1.4.3 并行性和效率
总线模块的设计允许FFT处理器同时处理多个数据点,从而提高计算速度和效率。并行性通过同时在不同地址上访问存储单元和传输数据来实现。数据总线的宽度和速度对于实现高吞吐量的FFT计算至关重要。控制单元负责生成控制信号,以协调地址总线和数据总线的使用。它确保数据在正确的时间传输,以支持FFT计算的正确执行。总线模块的设计和性能直接影响FFT处理器的整体性能。一个高效的总线系统可以大大提高计算速度和数据传输的效率,从而加速频谱分析或信号处理任务的完成。
2 基于FPGA的处理器实现
本研究设计的FFT大小为64点,浮点数精度为32位,选择64位数据宽度。系统时钟频率为100MHz。
2.1 控制单元实现
在FPGA设计中,控制单元核心部分是状态机的设计,状态机是一种有限状态自动机,用于管理FFT计算的不同阶段。这些阶段包括初始化、数据输入、蝶形运算和数据输出等。状态机的状态在时钟信号上升沿触发时更新。根据当前状态和输入信号,状态机会切换到下一个状态,在代码中使用了always块来描述状态机的行为。控制单元还需要实现启动和停止控制。这包括设计适当的控制信号,以启动FFT计算或停止计算。通常,这些信号可以通过外部输入或者通过FPGA编程来控制。这使得FFT处理器能够根据外部信号或者软件命令开始或停止计算。
此外,控制单元还可能需要与其他模块进行状态同步,以确保各个组件在正确的时间执行。例如,与蝶形运算单元和存储单元之间的状态同步是至关重要的,以确保数据在正确的时间传递和处理。
2.2 蝶形运算单元实现
2.2.1 模块定义
下面的代码定义了一个名为ButterflyUnit的Verilog模块,该模块包括输入和输出端口。输入包括两个复数数据点(实部和虚部),而输出包括一个复数数据点(实部和虚部)。
module…ButterflyUnit…(…………input…wire…[31:0]…input_data1_real,……//…输入数据1 的实部…………input…wire…[31:0]…input_data1_imag,……//…输入数据1 的虚部…………input…wire…[31:0]…input_data…………input…wire…[31:0]…input_data 2_real,……//…输入数据2 的实部2_imag,……//…输入数据2 的虚部…………output…wire…[31:0]…output_data_real,…//…输出数据的实部…………output…wire…[31:0]…output_data_imag……//…输出数据的虚部);
2.2.2 复数乘法
这部分计算了两个输入数据点的复数乘法。首先,实部相乘得到product_real,然后虚部相乘并相加得到product_imag。这两个值构成了复数乘法的结果。
//…复数乘法wire…[31:0]…product_real…=…input_data1_real…*…input_data2_real…-…input_data1_imag…*…input_data2 wire…[31:0]…product_imag…=…input_imag;_data1_real…*…input_data2_imag…+…input_data1_imag…*…input_data2_real;
2.2.3 复数加法
这部分计算了两个输入数据点的复数加法。它直接将实部和虚部分别相加,得到output_data_real和output_data_imag,它们构成了复数加法的结果。
//…复数加法assign…output_data_real…=…input_data1_real…+…input_data2_real;assign…output_data_imag…=…input_data1_imag…+…input_data2_imag;
2.3 旋转因子实现
旋转因子在FFT算法中表示为复数幅度为1的指数函数,其角度由FFT计算的当前阶段和频率决定。
module…TwiddleFactorGenerator…(…………input…wire…[7:0]…phase,…………………//…当前阶段(角度)输入,8 位二进制表示…………output…wire…[31:0]…twiddle_real,…//…旋转因子实部,32 位宽…………output…wire…[31:0]…twiddle_imag……//…旋转因子虚部,32 位宽)//…旋转因子计算always…@(*)…begin…………//…计算角度…………reg…[7:0]…angle…=…phase;…//…在实际应用中,可能需要更复杂的角度计算…………//…计算旋转因子…………assign…twiddle_real…=…$signed($bitstoreal({1'b0,…1'b0,…angle}))…/…256.0;…//…实部…………assign…twiddle_imag…=…$signed($bitstoreal({1'b0,…1'b1,…angle}))…/…256.0;…//…虚部end endmodule
该模块接受一个8位的角度输入作为phase,并输出32位的旋转因子的实部和虚部。生成的旋转因子的实部和虚部都是32位宽的有符号数,它们表示了复数形式的旋转因子。这些旋转因子用于后续的复数乘法操作,以实现频域的正确变换。
3 结论
本文详细讨论了基于FPGA的高性能FFT处理器的设计和实现。FFT是一种在信号处理、通信和图像处理等领域中广泛使用的算法,因此,在FPGA硬件平台上实现高性能的FFT处理器对于加速这些应用非常重要。在本文中论述了处理器的各个核心组成部分,包括控制单元、蝶形运算单元、存储单元和总线模块,并对控制单元和蝶形运算单元如何在FPGA实现给予了重点研究。