免费服务热线:020-988635871

产品列表

准备好将整个设计合在一起
发布时间:2019-03-10 22:29

  :快速傅里叶变换(FFT)是信号处理应用的基础。FPGA供应商一直以来提供了运行良好的FFT库,处理适配到FPGA片内存储器中的大量数据。但是,如果数据规模太大,应该如何应对? 为解决这一问题,FPGA设计人员现在必须要做出设计决定,这些决定互相纠缠在一起,例如,片内FFT内核的配置选择,其数量,它们怎样连接并访问外部存储器,多个内核之间的同步等。分析所有这类设计决定就是要能够很好的结合现有产品,在HDL中编程,这会非常耗时,而且带来了性能问题。采用OpenCL等高级编程语言,能够很快的完成系统设计分析。本

  摘要:快速傅里叶变换(FFT)是信号处理应用的基础。FPGA供应商一直以来提供了运行良好的FFT库,处理适配到FPGA片内存储器中的大量数据。但是,如果数据规模太大,应该如何应对? 为解决这一问题,FPGA设计人员现在必须要做出设计决定,这些决定互相纠缠在一起,例如,片内FFT内核的配置选择,其数量,它们怎样连接并访问外部存储器,多个内核之间的同步等。分析所有这类设计决定就是要能够很好的结合现有产品,在HDL中编程,这会非常耗时,而且带来了性能问题。采用OpenCL等高级编程语言,能够很快的完成系统设计分析。本文将研究在目前FPGA体系结构上实现1M和16M点数的频域滤波器,支持从每秒120到240百万采样的不同采样率。本文研究一个2M点数单精度频域滤波器的示例,该示例选择OpenCL作为其设计决定。假设读者熟悉FPGA设计,掌握OpenCL的基本概念。

  本文介绍构建一个百万点数单精度频域滤波器。这类滤波器使用百万点数1D FFT,将每一个频率和相位分量与用户提供的数值相乘,使其输入转换到频域,并通过FFT反变换,再把结果转换回时域。在目前一代FPGA和两个DDR3外部存储器块平台上,对于两百万点采样,整个系统的性能总要求是每秒处理1.50亿点(MSPS)。输入和输出通过万兆以太网直接传送给FPGA。

  对于这一设计,本文选择使用Altera OpenCL SDK,在安装了Stratix V GSD8 FPGA的BittWare S5-PCIe-HQ电路板上运行FPGA编译器。出于两个原因,选用OpenCL而不是更底层的语言。第一个原因是设计几百万点数的滤波器需要构建复杂而且非常高效的外部存储器系统。采用底层设计工具,建立片内FFT或者进行对角旋转的独立模块相对简单(特别是因为所有FPGA供应商已经提供了含有这类模块的库)。但是,建立外部存储器系统通常需要付出大量的HDL工作。由于在开始时并不知道整个系统的配置,因此这特别难,在后面会看到。选择OpenCL的第二个原因是通过主机控制FPGA逻辑。从开始时就清楚两个完整的几百万点的FFT内核副本无法适配到一个器件中,因此,在获得最终输出之前,一组数据至少要通过FPGA逻辑两次。协调这类共享同时还要实现动态修改数据规模、乘法系数,甚至完全修改FPGA功能等,这些工作最好留给CPU。为FPGA提供的OpenCL编译器解决了所有这些难题——它开发可定制的高效的外部存储器系统,能够精确地控制FPGA逻辑。

  假设已经有一个FFT内核,处理的数据长度完全能够适配到FPGA中(将其称之为“片内FFT”),每一家FPGA供应商都会提供此类内核。至少可以采用以下方式对这些内核配置参数:

  1. 数据类型(定点或者单精度浮点);2. 要处理的点数,N; 3.要并行处理的点数,POINTS;4. 动态支持修改要处理的点数。

  有了这类片内FFT内核后,需要两个步骤来构建整个系统:开发一个能够处理几百万点数的FFT内核,然后,把两个这类内核连接在一起,它们之间是复数乘法,从而建立完整的系统。

  采用外部存储来实现FFT的传统方法是六步算法[1],把一个一维数组当做两维来处理(2M = 2K x 1K),如图1所示。

  图1画出了六步算法,显示了单独的计算内核以及外部存储器缓冲。“获取”内核读取来自外部存储器的数据,以选择对其进行转置,将其输出至通道(在OpenCL 2.0术语中,也称之为“管道”)。在硬件中,以FIFO来实现通道,其深度由编译器计算。“片内1D FFT”是未经修改的供应商的FFT内核,接收输入,使用通道产生比特反转输出。“转置”是将从输入通道读取的数据转置,可以选择将其与特殊的旋转因子相乘,以自然顺序把输出写入到外部存储器。

  正如您从图1中所看到的,数据两次通过获取→1D FFT→转置(F1T)流水线,产生最终输出。留给第一个最重要的设计选择——采用一个F1T流水线副本以节省面积,或者两个副本以尽可能的提高吞吐量。

  在仿真器中对这一算法进行原型设计,以便能够正确的处理转置地址以及旋转因子。仿真器将OpenCL内核编译至x86-64二进制文件,可以运行在没有FPGA的开发板上。从仿真器到硬件编译是比较简单的步骤——仿真器中功能正确的代码在硬件中也是正确的,不需要仿真。出于性能和面积的原因,唯一要修改的是获取和转置内核所使用的本地存储器系统。高效的转置需要在本地存储器中对数据POINTS列/行进行缓冲。OpenCL编译器分析您OpenCL代码中对本地存储器的所有访问,并通过创建一个定制的片内存储系统来优化你的代码。对于POINTS=4的情况,最初的转置内核有四次写和四次读操作。一个双泵的片内RAM模块最多可以服务四个独立的申请,其中最多两次写操作。为支持四次写和四次读操作,需要复制片内存储器,含有申请仲裁逻辑,导致面积增大,性能下降。当认识到可以通过修改写模式,来连续进行所有四次写操作后,这四次写操作被OpenCL编译器分成一组,成为一次宽写操作,这样,只需要对本地存储器系统访问五次:一次写操作,四次读操作。进行了这一修改后,编译器自动为构建一个小很多的五端口存储器系统,在每一时钟周期可以服务所有五个申请,不会出现停顿。

  设计被编译到硬件中后,可以进行性能测量。在FPGA上有一个F1T流水线副本,对于四百万点FFT,测得了POINTS=4时,217 MSPS,POINTS=8时,457 MSPS[2]。POINTS=8版本使用了两次,因为这一配置中大量的片内模块RAM和两个副本无法适配。这就是要研究的第一个设计范围——要并行处理的点数和面积。

  现在,有了一个几百万点的FFT,准备好将整个设计合在一起。把两个片外FFT连接在一起,得到图2所示的流水线逻辑视图。