| **银杏科技有限公司旗下技术文档发布平台** |||| |技术支持电话|**0379-69926675-801**||| |技术支持邮件|Gingko@vip.163.com||| ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | V1.0 | 2020-02-28 | gingko | 初次建立 | ===== 实验二十:基于 FIFO 的 ARM+FPGA 数据存取实验 ===== ==== 一、 实验目的与意义 ==== - 了解 FIFO 读写的工作原理。 - 掌握 FIFO 使用方法。 - 学习 QuartusII 集成开发环境中FIFO IP核的调用及配置方法。 ==== 二、 实验设备及平台 ==== - iCore3 双核心板。[[https://item.taobao.com/item.htm?id=524229438677|点击购买]] - JLINK(或相同功能)仿真器。 - Blaster(或相同功能)仿真器和 USB 线缆。[[https://item.taobao.com/item.htm?id=554869837940|点击购买]] - Micro USB 线缆。 - QuartusII 开发平台。 - Keil MDK 开发平台。 - 装有 WIN XP(及更高版本)系统的计算机。 ==== 三、 实验原理 ==== * FIFO 是英文 First In First Out 的缩写,是一种先进先出的数据缓存器,特点是没有外部 读写地址线,只能顺序写入数据,顺序读出数据,其数据地址由内部读写指针自动加 1 完成。 * 根据工作时钟域的不同,可将FIFO分为同步FIFO和异步FIFO。同步FIFO的读写操作是同一个时钟。异步FIFO是指读写操作的时钟是相互独立的。因此在一些跨时钟域的数据传输时,可以用FIFO对数据做缓存处理。 * 基于 FIFO 的这些特点,本实验通过串口发送命令控制 FIFO 的读写操作。首先,Commix 向 ARM 发送命令,ARM 通过 FSMC 总线向 FIFO 中写入数据,当 ARM 读到满标志时,停止写入,自动从 fifo 中读取已写入的数据,通过串口显示出来,对比写入与读取数据的顺序与大小。实验原理图如图 1 所示 {{ :icore3:icore3_fpga_20_1.png?direct |}} ==== 四、 Quartus 内部 FIFO 模块调用 ==== 1、 打开 Tools——MegaWizard Plug-In Manager. {{ :icore3:icore3_fpga_20_2.png?direct |}} 2、 弹出界面里默认选择第一个,创建新的宏功能模块,然后直接点击 Next。如果已经建立了IP核,想要做参数的修改,可以在这一步选择第二个选项。 {{ :icore3:icore3_fpga_20_3.png?direct |}} {{ :icore3:icore3_fpga_20_4.png?direct |}} 3、 在Memory Complier下选择FIFO,如下图1所示。在下图中2所示位置选择FPGA类型,在3所示位置选择输出文件的命名,然后点击 Next。 {{ :icore3:icore3_fpga_20_5.png?direct |}} 4、接下来如图所示,设置FIFO的存储宽度为16bit,存储深度为256字节,类型设置为异步模式,即读写操作不使用同一个时钟信号。可以在左侧状态显示里看到当前设置的FIFO的控制信号和存储信息,核对无误后点击 Next 。 {{ :icore3:icore3_fpga_20_6.png?direct |}} 5、对FIFO进行优化类型的选择,该页面保持默认设置,直接点击 Next。 {{ :icore3:icore3_fpga_20_7.png?direct |}} 6、设置控制信号,这里勾选了写满标志位信号。FIFO 就建好了。 {{ :icore3:icore3_fpga_20_8.png?direct |}} 7、读取模式设置为预读取模式,即先读取一个数据,当rdreq有效时开始读取第二个数据。存储类型选择Auto,点击Next。 {{ :icore3:icore3_fpga_20_9.png?direct |}} 8、优化设置和仿真相关设置,参考下图设置,点击Next。 {{ :icore3:icore3_fpga_20_10.png?direct |}} {{ :icore3:icore3_fpga_20_11.png?direct |}} 9、点击Finish,完成FIFO的构建。 {{ :icore3:icore3_fpga_20_12.png?direct |}} ==== 五、代码讲解 ==== * FIFO作为一种先入先出的数据存储器,与普通存储器的区别是没有逮捕读写地址线,使用起来方便很多。作为一种先入先出数据存储器,只能顺序写入数据和顺序读出数据。因此,在代码编写时,需要处理好其时钟信号和读写控制信号。 * 本实验方案为STM32通过FSMC读写FIFO。因此,FPGA部分需要接受和提取STM32发送的读写信号和数据,并为FIFO提供时钟,实现FIFO的读写操作,代码参考如下 //--------------------ab_r------------------// reg [15:0]data_in; always @ (posedge wr or negedge rst_n) begin if(!rst_n) data_in <= 16'd0; else data_in <= db; //锁存数据 end //--------------------wr------------------// /*提取写信号*/ reg wr1,wr2; wire wr = (csn | wrn); //提取写信号 always @ (posedge pll_150m or negedge rst_n) begin if(!rst_n) begin wr1 <= 1'd0; wr2 <= 1'd0; end else begin {wr2,wr1} <= {wr1,wr}; end end //--------------------rd------------------// /*fifo读操作*/ wire rd = (csn | rdn); //提取读信号 assign db = rd ? 16'hzzzz : db_out; ==== 六、 实验步骤 ==== - 把仿真器与 iCore3 的 SWD 调试口连接(直接相连或者通过转换器相连); - 将 USB-Blaster 与 iCore3 的 JTAG 调试口相连; - 将跳线帽插在 USB UART; - 把 iCore3(USB_UART)通过 Micro USB 线与计算机连接,为 iCore3 供电; - 打开 Commix,找到对应的 COM 端口打开; - 打开 Quartus II 开发环境,并打开实验工程; - 烧写 FPGA 程序到 iCore3 上; - 打开 Keil MDK 开发环境,并打开实验工程; - 烧写 ARM 程序到 iCore3 上; - 输入串口命令,观察实验现象。 ==== 七、 实验现象 ==== * 在 Commix 界面对比 FIFO 写入数据与读取数据的大小和顺序,发现数据的大小和顺序保持一致。 * 命令格式: * 写命令:fifo+空格+write_read+\cr\lf * 例如:fifo write_read\cr\lf