1、信息与通信工程学院信号与信息处理综合实验报告(FPGA 部分)班 级:姓 名:学 号:序 号:实验三 用 FPGA 实现快速傅里叶变换一、 实验目的(1) 掌握 Xilinx ISE 中 IP Core 的使用方法;(2) 初步掌握 Xilinx 公司的 FFT IPCore 的使用方法;(3) 比较 DSP 和 FPGA 实现 FFT 的异同。二、 实验内容(1)按实验指导书所给出的步骤,用 Xilinx IP Core 实现 256 点的 FFT 并进行仿真和测试。(2)将所给出的例子改写为 512 点的 IFFT 并进行仿真和测试。三、实验过程说明1、 Xilinx FFT IPcore
2、 使用说明在 Xilinx 公司的 IPCore 中,提供两不同的架构: Burst I/O 架构和 Streaming I/O 流水线架构 。所谓的 Burst I/O 是指数据的输入和输出都是突发的,即输入输出是一段一段的而不是连续的;所谓的 Streaming I/O 流水线架构则是指输入数据和输出数据都是以一定的频率连续不断地进行的。Burst I/O 架构下,采用的是时间抽取(DIT)方法,而 在 Streaming I/O 流水线架构下采用的是频率抽取(DIF )方法。当采用基 4 分解时,N 点 FFT 共需 log4 (N) 级,每一级包含N/4 个基 4 的蝶形图,如果点数
3、N 不是 4 的幂次,则还需要另外一个基 2 的级。如果采用基 2 的分解,则共有 log2 (N)级,每一级包含 N/2 个基 2 蝶形。IFFT 通过将对应的 FFT 的相位因子取共轭实现。本实验以 Streaming I/O 流水线架构 为例学习 Xilinx FFT IPcore 的使用方法。Streaming I/O 流水线架构示意图如下图所示。这种架构将多个基 2 的蝶形处理单元排成流水线形式以提供连续的数据处理,每个处理单元有它自己的存储单元用于存储输入和中间数据。数据数据可以连续输入到流水线的前级,经过一段计算时延,从输出端连续输出一个数据块的数据。当然,这种架构也允许在数据块
4、之间添加一段时间的间隔。在 scaled fixed-point 模式下,数据在每进行一对基 2 级之后都会进行一次移位,移位次数可以事先根据输入数据范围确定。除了这种模式外,IP core 还提供一种块浮点模式用于改善性能。输出数据可以以比特逆序输出,也可以自然序输出,当采用自然序输出时,需要用到额外的存储资源。与 streaming I/O 架构不同,Burst I/O 以一组蝶形计算单元完成所有运算,其中基 4 的 Burst I/O 架构示意图如下图所示。在这种架构下,输入数据分为 4 块存储到 RAM 中,每计算一次蝶形运算,计算结果仍然存储到这 4 块 RAM 中,直至最后输出。在
5、这种架构下,数据不能连续输入,整个 IPcore 的工作状态分为数据输入、处理和输出等不同的状态。显然,这种架构占用资源量明显少于Streaming I/O 结构,但是处理数据的吞吐量有限。在不同的配置下,IPcore 对外的接口有一些差别,下面仅对在本实验中将要用到的部分端口的功能做以下说明:端口名 位宽 方向 描述Xn_re 可配 输入 输入数据实部,与xn_index对应Xn_im 可配 输入 输入数据虚部start 1 输入 启动控制信号,拉高则FFT开始加载数据,可一直置高,此时由IP core的状态控制加载Fwd_inv 1 输入 1表示FFT ,0表示IFFTScale_sch
6、在不同模式下位宽不同,在Streaming I/O模式下,输入 各级移位次数Sclr 1 输入 同步复位信号Clk 1 输入 工作时钟Xk_re 可配,scaled模式下同Xn_re输入 输入数据实部,与xn_index对应Xk_im 同上 输入 输入数据虚部Xn_index 与点数有关 输出 Xn所对应的序号Xk_index 与点数有关 输出 Xk所对应的序号RFD 1 输出 加载数据阶段为高Dv 1 输出 输出数据时为高2、 实验步骤(1) 新建工程;(2) 新建FFT IPcore。 命名为fft256,在IP列表中选择Digital signal processing-transfor
7、ms-FFTs,选择 7.1版本,点击Next ,然后点击 finish;(3) 在按以下截图下设置参数,然后点击Next(4) 在第2个页面上按下图设置,其含义分别为:定点格式;输入数据位宽16比特,相位因子16比特、Scaling选项选择scaled,截取模式选择truncation、添加同步复位sclr控制管脚、输出自然顺序,输入数据时序3 clock cycle offset选项。点击Next,进入第3页面(5) 第3页面上,选择Number of Stages using block ram为3,点击Generate 生成IPcore。(6) 新建block RAM IPcore,取
8、名为input_rom_I ;(7) 在第2页面上选择单口ROM,其他选项保持不变;(8) 第3页面设置如下图,注意选择use ENA pin选项;(9)第4页面上,选择下图中所示的两个寄存器选项;(10)选择压缩包中的input_I.coe 作为该ROM 的初始化文件;其他选项保持默认值,点击Generate ;(11)再按照上述步骤生成一个ROM,选择压缩包中的input_Q.coe文件作为初始化文件;(12)将压缩包中的fft_top.v,fft_ctrl.v 添加到工程中;(13)为fft_top.v编写测试文件,可参阅压缩包中的test_fft.v,注意理解程序中文件输出部分的功能;
9、(14)对该设计进行功能仿真,记录仿真波形,并分析Streaming I/O架构下256点FFT的计算时延;(15)使用Chipcope 对该设计进行在板测试,观察xn_index、xn_im、xn_re、xk_im、xk_re、xk_index的相对时序关系,触发条件可以xk_index、out_block_index或rd_block_index、xn_index取某一具体数值开始触发采数操作。(16)去掉cdc文件,在布局布线报告中找到 Device Utilization Summary部分,观察FFT部分的资源占用情况。(17)比较DSP实现FFT与FPGA 实现FFT 的异同。(1
10、8)(扩展功能)修改FFT点数为1024点,重新进行完成上述流程;(19)(扩展功能)将FFT IPcore改为Radix-4 Burst I/O架构,重新完成上述过程(注意,此时需要uload信号,直接在ctrl 模块里置1即可),并对streaming I/O方式的时延、吞吐量以及资源占用情况进行比较。四、实验代码分析程序模块描述:本次实验里涉及了三个程序,第一个是原始程序,另外两个是对原始程序作简单修改后的功能拓展,基本是类似的。以下只对原始程序作较为详细的说明,而功能拓展只简单说明修改的情况。本次实验主要通过 FPGA IPCore 实现。所谓 IP Core 就是预先设计好、经过严格
11、测试和优化后的电路功能模块。它犹如一个黑盒子,用户只需要配置好其相关接口并在顶层文件中将其实例化即可,但是它本质上也是一个 ISE 工程文件,存储在设计工程的 ipcore_dir 目录下,由于其代码本身过于复杂且本次实验中基本不涉及,因此下面不作介绍。本次实验全部采用以下两种 IP 核:Fast Fourier Transform(FFT )和 Block Memory Generator。1、256 点 FFT(Streaming I/O):(1)源程序(IP Core):FFT 核 1核名:fft256 ;架构:Streaming I/O(流水线);其它参数:工作频率 100MHz,定点
12、格式,输入数据位宽和相位因子位宽均为 16 比特,需要缩放,向下截取,顺序输出,添加同步复位 sclr 控制管脚,输入数据延迟 3 时钟周期等。调用该 IP Core 的控制信号将在介绍顶层文件时说明。存储器核 2全称:Block Memory Generator,可直译为块存储器生成器,可以生成任意大小的存储器阵列并可以针对速度或功率对其进行优化。本次实验使用它来生成存储器阵列,用于存储输入数据。由于输入数据(复数)的实部和虚部使用两个几乎完全相同的 IP 核,因此主要介绍实部使用的核,虚部使用的核若采用不同参数会在括号里注明。核名:input_rom_I(input_rom_Q);存储器类
13、型:单口 ROM;读取数据位宽:16 位;读取数据深度(个数):1024;使用的初始化文件:input_I.coe(input_Q.coe),存储了 1024 个 16 位数,表示输入数据的实部(虚部);使用使能管脚。(2)顶层文件(fft_top.v)及控制文件(fft_ctrl.v):重要的组成部分,对于工程的正确运行是必需的,其中顶层文件完成控制信号的声明,部分信号(主要为恒定信号)的赋值,接受来自控制文件的信号,利用信号实例化和调用所有 IP 核的任务,而控制信号则主要根据系统时钟及相关触发条件对控制信号及相关参数进行赋值,并将其结果返回给顶层文件。这两个文件的主要工作都是对相关控制信
14、号进行处理,下面介绍这些控制信号及它们在相关文件中是如何被处理的,通过这些基本就可了解这两个文件的内容。a. 输入(控制)信号:这里都是 IP 核的输入信号,需要在顶层文件或控制文件中对其初始化或赋值。FFT 核控制(输入)信号:XN_RE 和 XN_IM:输入操作数,分别代表实部和虚部,位宽为 16 位,表明实部和虚部都是 16 位。顶层文件中还包含 32 位的 XN 和 XK 信号也用来表示操作数,高 16 位表示实部,低 16 位表示虚部;START:FFT 开始信号,高有效,表明开始输入数据。控制文件中在一开始把它置为 1,但对于 Streaming I/O 结构而言,任何时候置 1
15、都可以开始数据的加载;FWD_INV:指示 IP Core 是 FFT 还是 IFFT,顶层文件中把它置 1 表明是FFT 运算;FWD_INV_WE:FWD_INV 端口的使能信号,由于这里自始至终都是进行FFT 运算,因此顶层文件中把它置 0 表明 FWD_INV 信号不再变化;SCALE_SCH:若选择在数据处理中进行缩放则需要此信号,流水线结构中,将每个基 2 的蝶形处理单元视为一个阶段,每个阶段进行一次数据的缩减,缩减的比例以此输入中对应阶段的两比特表示;SCALE_SCH_WE:SCALE_SCH 的使能信号,这里同样置 0 表示SCALE_SCH 不再变化;SCLR:FFT 核同
16、步复位信号,高有效,控制文件中置其为 0 表明不需要复位;CLK:输入时钟信号,实验中由 FPGA 板产生;XK_RE 及 XK_IM:输出的数据(补码形式),两个信号分别代表实部和虚部,实验中采用了缩放,因此这两个信号位宽和输入数据是相同的,都是16,输出的数据将存储在 XK 中;XN_INDEX:输入数据的下标,位宽等于以 2 为底 FFT 点数的对数,对于256 点 FFT 而言是 8 位;XK_INDEX:输出数据的下标,位宽与 XN_INDEX 相同;存储器核控制(输入)信号:本次实验中仅使用了端口 A,下面的信号都是针对它的。CLKA:端口 A 使用的时钟信号,这里和 CLK 是相
17、同的;ENA:端口 A 的使能信号,启用相关读写和复位操作,这里直接使用顶层文件中的 RD_EN(读使能)信号;ADDRA:该信号把相关地址赋给 A 端口以用于读写操作,这里直接使用顶层文件中的 RD_ADDR 信号(10 位);b. 输出(状态)信号:这些都是 IP 核的输出信号以表明工作状态,顶层文件和控制文件不需要对它们进行修改,但在调用 IP 核时仍需要声明它们,在仿真时通过观察这些信号的状态可以获得很多有用信息。RFD(Ready for data):FFT 核输出信号,当其为高时表明 FFT 核正在加载数据,当其由低变高时表明 FFT 核已经转备好接收数据;BUSY:FFT 核输出
18、信号,当其为高时表明 FFT 正在计算中;DV:FFT 核输出信号,当其为高时表明当前输出端口存在有效数据;EDONE:FFT 核输出信号,即将完成,在 DONE 之前一个周期给出高电平;DONE:FFT 核输出信号,当其为高时表明 FFT 已经计算完成,但高电平只持续一个时钟周期;DOUTA:存储器核输出信号,返回读操作中得到的数据,这里它用来返回从 input_i.coe 或 input_q.coe 文件中的数据,因此位宽为 16,返回的数据存储在XN 中;c. 其它信号:这里的信号和 IP 核无关,仅用在控制文件和顶层文件中,用于传递参数或显示相关状态,其中 XN 和 XK 信号前面已有
19、描述,这里不再重复。RESET:控制文件信号,在顶层文件中为 RST,来源为 FPGA 板,当其为高电平时,块序号清零(下面会介绍),注意 FFT 核也有一个控制信号RESET,但是和这里介绍的无关,顶层文件实例化 FFT 核时没有使用 RESET信号;RD_EN:从 ROM 中读取数据的使能信号,这里直接使用 FFT 核的 RFD信号,即:一旦 FFT 核已经准备好或正在接收数据,就读取新数据;WR_EN:往 RAM 里写数据的使能信号,这里直接使用 FFT 核的 DV 信号,即:一旦 FFT 核开始输出有效数据,就开始写入这些数据;RD_ADDR:读取数据的地址,10 位(表示 1024
20、个数),在这里由 2 位块序号和 8 位输入数据序号组成,见下面的相关说明;RD_BLOCK_INDEX:表示数据块的序号,读操作用,2 位,可表示 4 个ROM 块,由于输入数据有 1024 个,而输入序号 XN_INDEX 和 XK_INDEX 都是 8 位,最多表示 256 个数,因此需要 4 个 ROM 块来管理所有输入数据,每个块存储 256 个数,控制文件中,当数据序号达到 255(即已有 256 个数据)时,该信号加一表明开始启用下一个 ROM 块,块序号(2 位)和输入序号(8位)共同组成 RD_ADDR 信号指示数据地址;OUT_BLOCK_INDEX:表示数据块的序号,写操
21、作用,2 位,和RD_BLOCK_INDEX 性质相同;OUTPUT_RE:输出数据的实部,16 位,直接使用 XK 的高 16 位;OUTPUT_IM:输出数据的虚部,16 位,直接使用 XK 的低 16 位;(3)测试文件(test_fft.v):该文件对于工程的正常运行不是必需的,它仅用在 Modelsim 仿真中,也是通过相关信号的处理来构建仿真环境,以下简要介绍它的工作流程(其中所有信号都将送给顶层文件)。打开(或创建)文件 output_data.txt,对应的语句语句为 “fp = $fopen(“output_data.txt“)”;开始置写使能(WF_en )信号为高,计数器
22、( counter)为 0;产生周期为 10ns 时钟信号 CLK,并向顶层文件中输出,作为系统时钟;在每一个时钟的上升沿,若 FFT 核输出的 DV 为高电平(表明数据有效),则向文件 output_data.txt 中写入输出的有效数据,数据源自顶层文件的OUTPUT_RE 和 OUTPUT_IM,将被转换成十进制,写入文件的语句为“$fdisplay(fp, “%d %d“, output_re, output_im)”,写入数据的形式为无符号十进制数,同时计数器值加 1;若计数器值变为 1023,即已写入了 1024 个数,则置写使能信号为低,停止写入。以上流程结束后,在 Models
23、im 中显示波形的同时,工程目录下将多出一个output_data.txt 文件,存储了一次 FFT 运算的结果。若延长仿真时间,则 FFT核还会输出相同的数据,但它们将不会被写入文件中。2、1024 点 FFT(Streaming I/O):这是源程序的功能拓展,基本内容和源程序是相同的,以下只说明需要修改的地方。在 FFT 核设置的第一页,把点数改成 1024,其它设置无需改动,改完后需要重新生成 IP 核;XN_INDEX 和 XK_INDEX 位宽是以 2 为底 FFT 点数的对数,因此对于1024 点数 FFT 来说应从 8 位改成 10 位;SCALE_SCH 信号的位宽为 ,其中
24、 NFFT 为 FFT 点数,因此对2log2NFFT2 于 1024 点 FFT 来说应改为 10 位,这里按照 XILINX 官方说明文件(见下面截图)的内容将其改为 1010101010;(对于 SCALE_SCH 的取值, XILINX 官方文件也给出了其它方案,下面给出另一个截图,这段叙述给出了 SCALE_SCH 的意义所在,即每两个比特对应输入中某阶段即每个蝶形运算的压缩比例。按照这段内容的说法,若将SCALE_SCH 改成 1010101011 可以完全避免数据溢出的情况,但是由于时间所限我没有进行测试。)对于上面的 256 点 FFT 而言,由于 XN_INDEX 和 XK_
25、INDEX 都是 8 位,最多表示 256 个数,而输入的却有 1024 个,因此前面需要添加两位块序号,使用 4 块 ROM 进行管理,而对于 1024 点 FFT 来说,XN_INDEX 和 XK_INDEX都是 10 位,不需要使用块序号进行管理,也就是说 RD_BLOCK_INDEX 和OUT_BLOCK_INDEX 已经没有存在的意义,需要去掉或者屏蔽掉它们,按照以下方法即可实现:把语句“assign rd_addr = rd_block_index, xn_index”改成“assign rd_addr = xn_index”(必要步骤),然后删掉 RD_BLOCK_INDEX 和
26、OUT_BLOCK_INDEX 的声明语句和调用语句(不是必要的步骤)。3、256 点 FFT(Radix-4,Burst I/O)这是源程序的功能拓展,基本内容和源程序是相同的,以下只说明需要修改的地方。在 FFT 核设置的第一页,把类型改成 “Radix-4, Burst I/O”,其它设置无需改动,改完后需要重新生成 IP 核;添加 UNLOAD 信号(实验指导书上把它错打成了“uload”),它仅用在Burst I/O 结构的 FFT 核中,表示将开始输出处理的结果,添加的具体方法如下:在顶层文件实例化 FFT 核模块和控制文件模块加入语句“.unload(unload),”;控制文件
27、中加入语句“assign unload = 1;”,模块声明(module fft_ctrl)部分加入“output unload, ”,表明该信号的值将从控制文件传递到顶层文件中。以上功能拓展,若要进行 Chipscope 在板调试,还要对 CDC 文件和 UCF 文件进行修改,但我这次只进行了 Modelsim 的仿真,因此无法给出 CDC 文件和UCF 文件的修改方案。五、实验结果分析1. 256点FFT的modelsim仿真:仿真可大致分为4个阶段:第一阶段,模拟实际系统的初始化,除了打开或创建用于写入结果的文件output_data.txt外不进行任何操作;第二阶段,系统开始工作,开
28、始会有一个短暂的重置时间(RST信号为0),这时清空块序号OUT_BLOCK_INDEX和RD_BLOCK_INDEX,这段时间里RFD信号也变为高表示FFT核已经准备好接收数据,重置过后正式开始FFT 计算,这段时间虽然系统暂时不会有任何输出,但从RD_BLOCK_INDEX的变化上可以看出数据已经开始加载,每加载256个输入数值该信号会加1;第三阶段,开始输出有效数据,DV信号变为高,此时OUTPUT_RE和OUTPUT_IM开始输出计算结果,由于WF_en信号为高电平,结果也被写入文件中,为确保只写入一次计算结果计数器COUNTER 也将开始工作,这段时间里,每输出256个数据,OUT_
29、BLOCK_INDEX信号都将加1;第四阶段,一次FFT结果已经全部写入文件,计数器值变为 1023,此时置WF_en为0停止写入,计算器也清零停止工作,但是数据的加载没有结束,FFT还将重复输出前面的结果,DV信号仍为高电平,以后无论怎样延长仿真时间,都将停留在这个阶段,即只输出FFT结果但不写入文件的阶段。结果见下图:仿真完成后output_data.txt 的内容,默认为按2进制显示,将其改为按无符号数显示时,可以看到输出的结果已经写入到文件中,且写入形式为无符号数。若将输出的信号改为有符号数,则与老师给的 output.txt 文件内容对应,当然,这里只是改变了显示的形式,实际处理和写
30、入时仍按照无符号数进行。计算延时:这段时间严格来说应该是从数据开始输入(加载)到第一个有效数据输出这段时间,根据图中数据可以判断,延时为 6094737ps。2.256 点 FFT 的 Chipscope 测试波形分析:以下先介绍我的 Chipscope 内核定义文件是如何设置的。Trigger Parameters 选项卡里,Trigger Ports 设为 1,Trigger Width 设为 20,即 1 个触发源,里面包含 20 个触发信号,触发信号至少应为 10 个,另外更好的设置方案是设置 2 个触发源,每个触发源设置 10 个信号,具体下面会说明;Capture Paramete
31、rs 选项卡里,去掉 Data Same As Trigger 选项,设置 Data Width 为 113,即 113 个数据信号;Net Connections 选项卡里,按下设置信号连接:Clock Signals 里设置时钟源为fft_top 模块下的 clk_BUFGP;Trigger Signals 里设置触发源为fft_top 模块下的ctrl_inst/out_block_index( 2 位),ctrl_inst/rd_block_index (2 位),xk_index(8 位)和 xn_index(8 位),共 20 个触发信号(更好的设置方案是设置两个触发源,一个触发源
32、包含 out_block_index 和 xk_index 共 10 位信号,另一个包含 rd_block_index 和 xn_index 共 10 位信号,最小的设置方案是至少设置以上任何一个触发源,否则采集的数据会不正确);Data Signals 共包含 113 个信号,分别是fft_top下的 output_re(16 位)、output_im(16 位)、xn_index(8 位)和 xk_index(8 位),fft_inst 下的xn_re( 16 位)、xn_im( 16 位)、xk_re (16 位)、 xk_im(16 位)和 dv 信号(1 位)。实验结果如下:可以看到
33、图中数据与理论值一致要获得图中的显示结果,需把所有数值按无符号数显示,另外若 output 信号展开后序号从高到低,需要反转这个显示顺序,改成序号从低到高。如果运行正确的话,output 信号输出的数据在 output_data.txt 可以查找到,若 output 信号是按有符号数显示的,则数据可以在 output.txt 中可以查找到,和Modelsim 仿真类似,说明了 Chipscope 仿真和 Modelsim 仿真获得的计算结果是相同的,这里不再给出对应的截图。要说明的是,Chipscope 仿真不产生结果文件,欲比较结果需要事先执行 Modelsim 仿真。3. 去掉 cdc 文
34、件,在布局布线报告中找到 Device Utilization Summary 部分,观察 FFT 部分的资源占用情况:结果如下:4.1024 点 FFT 的 modelsim 仿真:结果如下图:可以看到波形和 256 点 FFT 差不多,数据也和理论值相符。可见延时为 21585100ps,可以看到比之前的 256 点 FFT 的延时长很多。5. 256 点 FFT(Radix-4,Burst I/O):将FFT IPcore改为Radix-4 Burst I/O架构,重新完成上述过程,并对streaming I/O方式的时延、吞吐量以及资源占用情况进行比较。结果如下图:在 DV 数据有效信
35、号为 1 前就输出了四组数据,这种现象是正常的。在 Burst I/O 架构下,输入数据分为 4 块存储到 RAM 中,每计算一次蝶形运算,计算结果仍然存储到这 4 块 RAM 中,直至最后输出。在这种架构下,数据不能连续输入,整个 IPcore 的工作状态分为数据输入、处理和输出等不同的状态。整个仿真中,包含了 4 次把计算出的临时数据存储到 RAM 又读出的过程,才会出现这种情况。虽然输出了四组数据,但 FFT 核判定这些数据都不是有效的,DV 信号保持为 0,因此它们也不会被写入文件中。如果延长仿真时间,这种现象会一再出现。图中可以看出延时大约为 6070000 左右,和原程序的结果差不
36、多。一般来说,采用基 4 算法速度应该快于基 2 算法,这里计算时间没有大幅缩短的原因是采用了 Burst I/O 结构,不能处理连续数据,处理时间较长。资源占用情况见下表:Device Utilization Summary -Slice Logic Utilization Used Available Utilization Note(s)Number of Slice Registers 2,575 11,440 22% Number used as Flip Flops 2,575 Number used as Latches 0 Number used as Latch-thrus
37、0 Number used as AND/OR logics 0 Number of Slice LUTs 1,627 5,720 28% Number used as logic 1,200 5,720 20% Number using O6 output only 517 Number using O5 output only 22 Number using O5 and O6 661 Number used as ROM 0 Number used as Memory 336 1,440 23% Number used as Dual Port RAM 0 Number used as
38、Single Port RAM 0 Number used as Shift Register 336 Number using O6 output only 53 Number using O5 output only 0 Number using O5 and O6 283 Number used exclusively as route-thrus 91 Number with same-slice register load 82 Number with same-slice carry load 9 Number with other load 0 Number of occupie
39、d Slices 662 1,430 46% Number of LUT Flip Flop pairs used 2,002 Number with an unused Flip Flop 87 2,002 4% Number with an unused LUT 375 2,002 18% Number of fully used LUT-FF pairs 1,540 2,002 76% Number of unique control sets 29 Number of slice register sites lostto control set restrictions150 11,
40、440 1% Number of bonded IOBs 37 102 36% Number of LOCed IOBs 22 37 59% Number of RAMB16BWERs 2 32 6% Number of RAMB8BWERs 5 64 7% Number of BUFIO2/BUFIO2_2CLKs 0 32 0% Number of BUFIO2FB/BUFIO2FB_2CLKs 0 32 0% Number of BUFG/BUFGMUXs 1 16 6% Number used as BUFGs 1 Number used as BUFGMUX 0 Number of
41、DCM/DCM_CLKGENs 0 4 0% Number of ILOGIC2/ISERDES2s 0 200 0% Number of IODELAY2/IODRP2/IODRP2_MCBs 0 200 0% Number of OLOGIC2/OSERDES2s 0 200 0% Number of BSCANs 0 4 0% Number of BUFHs 0 128 0% Number of BUFPLLs 0 8 0% Number of BUFPLL_MCBs 0 4 0% Number of DSP48A1s 12 16 75% Number of ICAPs 0 1 0% N
42、umber of MCBs 0 2 0% Number of PCILOGICSEs 0 2 0% Number of PLL_ADVs 0 2 0% Number of PMVs 0 1 0% Number of STARTUPs 0 1 0% Number of SUSPEND_SYNCs 0 1 0% Average Fanout of Non-Clock Nets 2.07 对上面的报告对比可以发现,采用 Burst I/O 架构占用资源要比 Streaming I/O 架构占用资源少,但这是以延长处理时间为代价的。六、遇到的问题:1.无法出现波形:连接到 modelsim 出现问题或
43、仿真时间不对2. Chipscope 显示的结果不正确:需要用反序显示才能得到正确结果3.由于理解不太清楚,出现过改错删错东西的状况,是结果出不来七、比较 DSP 实现 FFT 与 FPGA 实现 FFT 的异同:在开发方面,这学期所做的 DSP 实验和 FPGA 实验都涉及到了 FFT,我认为 DSP 的 FFT 开发过程要比 FPGA 简单得多,首先开发 DSP 过程使用的是 C语言,在理解 FFT 算法的具体过程后甚至可以自己编写代码,更不用说 DSP 函数库里已经自带了很多 FFT 函数,可直接调用,当然在 FPGA 的实验中,我们使用了类似 DSP 函数库的实现办法,就是 IP 核,
44、但是它本身使用起来就比较麻烦,不能独立工作,需要了解它的控制信号和大致工作过程,并另外编写文件利用这些信号来实现对 IP 核的调用,若是自己使用 Verilog 语言编写 FFT,那想必更是一个痛苦的事情(IP 核本身就是一个 ISE 工程,FFT 核的代码我看了一下,光文件大小就有近 2MB,代码本身 60000 多行),主要原因还是Verilog 对浮点运算的支持有限。即便编写好了代码想要运行,DSP 只需要编译,而 FPGA 编译完了还需要综合和布局布线,因此用 FPGA 实现 FFT 不仅比 DSP麻烦且实现过程本身还很耗时。虽然用 FPGA 实现 FFT 比较麻烦,但它仍然拥有自己的
45、优势,尽管 DSP芯片的强项就是数字信号处理,其本身也针对这点作了不少的优化, 例如它的浮点运算比 FPGA 要强,可 DSP 本身有一个致命缺陷就是处理速度远不如FPGA。FPGA 并行运算能力比 DSP 强很多,此外它灵活性也很强,对于数据可变宽度或者采样速率多变的情况 DSP 芯片不能适应而 FPGA 就做得更好。就开发本身而言,看似 FPGA 需要长时间的综合和布局布线,但是那是一个相当于把高级语言翻译成机器语言的过程(个人理解),把每一步操作转换成简单的逻辑运算(FPGA 本身由大量的可编程逻辑门组成),当然执行起来要快得多,而 DSP 开发时使用的 C 语言运行效率自然要低不少。总
46、的来说,用 FPGA 实现 FFT 比 DSP 要麻烦甚至难很多,但与此同时FPGA 的运行速度和效率要比 DSP 强不少,在我看来,对于初学者无疑用 DSP实现 FFT 更方便,但对于追求高效率高速度的专业人员而言,FPGA 应该是更好的选择。八、实验总结:通过这次实验,我掌握 Xilinx ISE 中 IP Core 的使用方法,同时也初步掌握Xilinx 公司的 FFT IPCore 的使用方法。通过用 FPGA 实现 256 点 FFT 和 1024点 FFT,使我对软件的应用和调试更加熟练,同时在分析实验结果的波形和数据时复习了 DSP 中关于 FFT 的相关知识,通过实验促进了对这部分知识的进一步理解和掌握。实验中也比较了 DSP 和 FPGA 实现 FFT 的异同,通过深度研究弄清楚了这两者的区别。这次实验难度也不小,在实验过程中也出现了不少问题,通过对错误的查看分析寻找解决方法,增强了我们的分析能力、动手能力以及解决问题的能力。实验中对不同的方式及数据有多次比较,使我们学会了通过比较寻找异同从而更加了解本质的原理,是一种很好的处理问题的方式。总之,这次实验大大促进了我的实验能力,也增强了对相关理论知识的进一步融会贯通,确实学到了很多东西。