本帖最后由 芯航线跑堂 于 2017-1-4 17:01 编辑
嵌入式块RAM使用之FIFO
实验目的:学会配置Altera提供的FIFO核并通过仿真了解其接口时序 实验平台:无 实验原理: 1.FIFO概念 FIFO的完整英文拼写为First In First Out,即先进先出。FPGA或者ASIC中使用到的FIFO一般指的是对数据的存储具有先进先出特性的一个存储器,常被用于数据的缓存或者高速异步数据的交互。 2.FIFO结构 FIFO从大的情况来分,有两类结构:单时钟FIFO(SCFIFO)和双时钟FIFO(DCFIFO),其中双时钟FIFO又可以分为普通双时钟(DCFIFO)和混合宽度双时钟FIFO (DCFIFO_MIXED_WIDTHS)。三种FIFO结构的英文含义如下所示: • SCFIFO: single-clock FIFO • DCFIFO: dual-clock FIFO(supports same port widths for input and output data) • DCFIFO_MIXED_WIDTHS:dual-clock FIFO (supports different port widths for input and output data) 注意: 在没有特别指明的情况下,混合宽度双时钟FIFO和双时钟FIFO统称为双时钟FIFO。 从图中我们可以看到,单时钟FIFO具有一个独立的时钟端口clock,因此所有输入信号的读取都是在clock的上升沿进行的,所有输出信号的变化也是在clock信号的上升沿的控制下进行的,即单时钟FIFO的所有输入输出信号都是同步于clock信号的。而在双时钟FIFO结构中,写端口和读端口分别有独立的时钟,所有与写相关的信号都是同步于写时钟wrclk的,所有与读相关的信号都是同步于读时钟rdclk的。在双时钟FIFO的符号图中,位于上部分的为与写相关的所有信号,位于中间部分的为与读相关的所有信号,位于下部的为异步清零信号。 图15-1单时钟FIFO与双时钟FIFO的符号图 3.不同结构FIFO的作用 单时钟FIFO: 单时钟FIFO常用于片内数据交互,例如,在FPGA的控制下从外部传感器读取到的一连串传感器数据,首先被写入FIFO中,然后再以UART串口的数据发送速率将数据依次发送出去。由于传感器的单次读取数据可能很快,但并不是时刻都需要采集数据,例如某传感器使用SPI接口的协议,FPGA以2M的SPI数据速率从该传感器中读取20个数据,然后以9600的波特率通过串口发送出去。此过程每秒钟执行一次。因为2M的数据速率远高于串口9600的波特率,因此需要将从传感器中采集到的数据首先用FIFO缓存起来,然后再以串口的数据速率缓慢发送出去。这里,由于传感器数据的读取和串口数据的发送都是可以同步于同一个时钟的,因此可以使用单时钟结构的FIFO来实现此功能。 双时钟FIFO: 双时钟FIFO的一个典型应用就是异步数据的收发。 所谓异步数据是指数据的发送端和接收端分别同步与不同的时钟域,使用双时钟FIFO的独立的读写时钟结构,能够将不同时钟域中的数据同步到所需的时钟域系统中。例如,在一个高速数据采集系统中,实现将高速ADC采集的数据通过千兆以太网发送到PC机。ADC的采样时钟(CLK1)由外部专用锁相环芯片产生,则高速ADC采样得到的数据就是同步于该时钟信号的,在FPGA内部,如果FPGA工作时钟(CLK2)是由独立的时钟芯片加片上锁相环产生的,则CLK1和CLK2就是两个不同域的时钟,他们的频率和相位没有必然的联系,假如CLK1为65M,CLK2为125M,那么就不能使用125M的数据来直接采集65M速率的数据,因为两者数据速率不匹配,在采集过程中会出现包括亚稳态问题在内的一系列问题,所以这里就可以使用一个具备双时钟结构的FIFO来进行异步数据的收发。图15-2为使用FIFO进行异步数据收发的简易系统框图。 图15-2基于千兆以太网传输的高速数据采集(8bit)系统 在此系统中,由于ADC的数据位宽为8位,基于UDP协议的以太网发送模块所需的数据也是8位,因此使用的是非混合宽度的双时钟FIFO结构。假如CLK1的频率为20M,ADC的数据位宽为16位,则可以使用混合宽度的双时钟FIFO,在实现异步时钟域数据收发的同时,实现数据位宽的转换。通过设置双时钟FIFO的写入位宽为16位,读取位宽为8位,则可以实现将16位的ADC数据转换为以太网支持的8位发送数据,然后通过以太网发送到PC机。 4.实现FIFO的方法 在AlteraFPGA中使用FIFO实现用户功能设计主要有三种实现方式。 第一种为用户根据需求自己编写FIFO逻辑,当用户对于FIFO的功能有特殊需求时,可以使用此种方式实现,但此种方式要求用户有较高的RTL设计能力。 第二种方式为使用第三方提供的开源IP核,此种IP核以源码的形式提供,能够快速的应用到用户系统中,当用户对FIFO功能有特殊需求时,可以在此源码的基础上进行修改,以适应自己的系统需求。 第三种方式为使用QuartusII软件提供的免费FIFO IP核,此种方式下,Quartus II软件为用户提供了友好的图形化界面方便用户对FIFO的各种参数和结构进行配置,生成的FIFO IP核针对Altera不同系列的器件,还可以实现结构上的优化。该FIFO IP核也是通过Verilog语言进行描述的,在Quartus II13.0软件中,该IP核源码存放于QuartusII软件安装目录quartus\eda\sim_lib下的altera_mf.v文件中的第48189行(scfifo)(dcfifo结构较多,因此代码内容很多,与之相关的代码有几千行,大家可以在文件中搜索dcfifo即可找到)。由于该FIFOIP核已经提供了几乎我们设计所需的所有功能,因此在系统设计中,推荐大家使用该FIFO IP核进行系统设计。 实验步骤: 新建一个以名为fifo的工程保存在prj下,然后单击Tools—MegaWizard Plug-In Manager来启动Mega Wizard插件管理器,并新建一个IP核。选择MemoryCompiler下的FIFO,并将输出目录确定为工程文件夹下的ip文件夹,并以fifo保存,单击Next。 图15-3-1 创建FIFO IP 这里首先创建一个单时钟FIFO也就是SCFIFO,数据位宽为16bits,数据深度为256words。这里修改数据位宽及深度,观察界面左下角的资源使用情况。 图15-3-2 定义FIFO类型以及位宽、深度 FIFO提供了很多接口,这里仅选择满、空、接近满、接近空以及异步清零。Almost_full,当usedw大于等于设置的值时该信号为高电平,是full的提前提示信号。Almost_empty,当usedw小于等于设置的值时该信号为低电平,是empty的提前提示信号。 图15-3-3 定义FIFO接口 读操作请求确认信号,有两种模式:普通模式与前显(show-ahead)模式。 图15-3-4 定义读请求信号以及块模式 面积优先还是速度优先。更换可以看到资源占用率是不一样的,选择速度优先必然使用资源会上升。 图15-3-5 定义优化策略 然后确定配置信息后即可点击Finish完成配置。 并将生成的IP核加入工程,即可在工程下看到加入的IP核文件并设置为顶层文件。 为了测试仿真编写测试激励文件,新建fifo_tb.v文件并输入以下内容再次进行分析和综合直至没有错误以及警告,保存到testbench文件夹下。除了实现例化需要仿真的文件以及时钟创建,还需实现写入256个数据后并依次读出。
这里介绍如何使用软件提供的模板进行设计。单击工具栏的 在User上右键New Template,可以输入自己模板例如 这样下次就可以直接调用。 图15-4-1创建模板 图15-4-2创建模板 设置好仿真脚本后进行功能仿真,可以看到如图15-5所示的波形文件。可以看出整体看来实现了数据的写入与读出。放大写数据部分,可以看到每当时钟上升沿时均会写入对应的数据,且empty信号在写入一个数据后即置低,almost_empty信号在写入两个数据后即置低。符合前面有关的配置。 在数据持续写入254个后almost_full信号置高,在写入256个后full信号置高。在读取使能信号有效后,读出一个数据后full信号置低同样读出2个数据后almost_full信号置低。 需指出这里usedw在写入255个数据后再写入第256个数据之所以变为0,是因为在前面设置种此数据的位宽是8位,因此最大计数到255。这里可以同时判断full的状态来判断实际剩余数据个数。同时选中full与usedw,右键选择Combine Signals,在弹出的图 中将合并后的信号命名为usedw2。这样重启仿真即可看到图15-7所示的波形,这时usedw2即为真实FIFO中数据个数。 在读取254个信号后almost_empty信号置高,继续读取一个数据后empty信号置高。如图15-8所示。 图15-5-1SCFIFO数据写入与读取仿真波形 图15-5-2SCFIFO数据写入部分波形 图15-5-3SCFIFO数据写入以及读取部分波形 图15-6-1合并信号 图15-6-2合并信号 图15-7usedw2功能仿真波形 图15-8almost_empty 与empty信号功能仿真波形 这样就完成了一个单时钟FIFO的配置以及仿真。 现在再新建一个FIFO并以mydcfifo保存。配置为双时钟FIFO也就是DCFIFO,且写入读取宽度分别为16\8bits。
图15-9-1DCFIFO不同宽度配置 这里关于双时钟潜伏期问题可以参考IP手册得以了解。 图15-9-2配置双时钟潜伏期 输入信号接口选择empty与usedw输出信号端口选择full与usedw,这里可根据实际需求情况进行选择。 图15-9-3DCFIFO接口配置 图15-9-4DCFIFO读请求以及块模式选择 图15-9-5 DCFIFO优化策略选择 然后预览汇总信息,确认后即可点击Finish来完成此IP的配置并将其加入工程中设置为顶层文件。 为了测试仿真编写测试激励文件,新建mydcfifo_tb.v文件并输入以下内容再次进行分析和综合直至没有错误以及警告,保存到testbench文件夹下。这里首先定义产生了不同的读写时钟频率,然后写使能即每当写时钟到来时就依次写入数据,写入256个数据后写失能,开始读使能即每当读时钟到来时依次读出数据,读出512个数据后读失能。这里由于写的数据为16位256个,因此也就相当于读出8位512个。 在写入数据时人为加了1024,这样写入数据实际就是04、14\24…..LSB,读取时就是2534\2544\2554.且读取empty正常显示。
设置好仿真脚本后进行功能仿真,可以看到如图15-10所示的波形文件。可以看出写入时地址每次加2而不是加1,与前面解释一致 。同时第一个数据是‘d1025=’b0100 0000 0001 分成两个8位十六进制数即为4、1,低位在前,符合设计。同样可以分析出读出数据规则。 图15-10-1写数据部分仿真波形 图15-10-2读数据部分仿真波形 这样一个FIFO的设计即为结束。本节讲解了FIFO的基本概念及其分类,实现了SCFIFO与DCFIFO的配置且进行了仿真。
小梅哥 芯航线电子工作室
|