用户工具

站点工具


icore4tx_fpga_22
银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
版本 日期 作者 修改内容
V1.0 2020-07-01 gingko 初次建立


实验二十二:FIFO实验——基于FIFO的ARM与FPGA数据存取

一、 实验目的与意义

  1. 掌握双口RAM IP核的调用及例化方法。
  2. 掌握RAM读写时序。
  3. 掌握QuartusII的使用方法。

二、 实验设备及平台

  1. iCore4TX 双核心板点击购买
  2. USB-CABLE(或相同功能)仿真器。
  3. JLINK(或相同功能)仿真器。
  4. Micro USB线缆。
  5. Keil MDK 开发平台。
  6. ISE开发平台。
  7. 电脑一台。

三、 实验原理

  • FIFO(First Input First Output)是一种先进先出存储器。与之前的RAM相比较而言,FIFO存储器没有地址线,操作起来更加的简单,但其缺点就在于,只能顺序读写数据,不能随意指定读写数据的地址单元。根据读写时钟的相同与否,FIFO可分为异步FIFO和同步FIFO两种,本实验讲的是异步FIFO。
  • FIFO的读写时钟在每个时钟上升沿到来时对数据进行操作;读写请求信号为高电平有效,低电平失能。
  • FIFO读写操作的工作原理:在FIFO内部有读写指针,其中,读指针指向下一个将要读取数据的地址,复位时指针指向0地址;写指针指向下一个将要写入数据的地址,复位指针指向0地址。
  • FIFO的空/满检测是FIFO应用中的一个重要参数,不过在应用过程中,这两项参数不是必须使用的,可以通过控制读写时钟及读写请求信号来避免溢出,即通过人为的控制数据长度避免读写溢出(本实验即使如此)。
  • 根据上面的介绍可知,FIFO的读写操作时序如图22.1所示。

22-1(a)读操作时序 读操作时序 22-1(b)写操作时序 写操作时序

  • 本实验基于ARM+FPGA构架,通过SPI实现ARM与FPGA之间通信,ARM通过SPI总线向FPGA发送相关指令;FPGA内部例化的FIFO作为ARM的外部存储器,根据指令进行对应的读写操作,从而实现ARM对FPGA内部FIFO的数据读写功能。实验流程较为简单,重点是掌握FIFO IP核的调用及时序的描述。

四、 FIFO IP核调用

1、新建一个工程名为fifo的工程,然后选中工程右击,下拉菜单中选择New Source…,如图22-2所示。 图22-2 2、弹出窗口选择新建IP核文件,既IP(CORE Generator & Architecture Wizard)选项。右侧的File name栏给IP核文件命名为fifo,点击Next。 图22-3 3、弹出IP核选择界面,点击Memories & Storage Elements 前面的“+”,再点击FIFOs前面的“+”,然后点击FIFO Generator选定,点击Next。 图22-4 4、点击Finish。 图22-5 5、弹出FIFO IP核相关参数设置界面,如下图所示,这里的Interface Type 选择Native,然后点击Next。 图22-6 6、选择时钟和存储器类型。本实验对FIFO的读和写是独立操作的,因此时钟选择异步模式;block RAM 是FPGA内部定制的RAM资源,Distributed RAM则是由LUT构成的RAM资源。所以本实验FIFO Implementation栏下选择Independent Clocks(RD_CLK,WR_CLK) Block RAM,然后点击Next。 图22-7 7、如下界面中设置Read Mode为Standard FIFO,;设置FIFO的读和写的位宽为8,写深度参数为1024,读深度根据这几个参数自动计算出来为1024;这里需要注意的是Write Depth参数设置为1024,Actual Write Depth为1023。 图22-8 8、此界面默认选项即可,点击Next。 图22-9 9、这里Initialization栏下取消复位引脚,然后点击Next。 图22-10 10、此界面默认,点击Next。 图22-11 11、点击Generate,生成FIFO IP核文件。 图22-12 12、在工程目录栏选中FIFO IP核文件,然后点击Processes: u0-spi_fifo窗口CORE Generator前面的“+”。双击View HDL Instantiation Template,可以看到所有需要例化的FIFO端口信号。 图22-13

五、 代码讲解

  • IP核调用只是生成相关的模块文件,在应用中要实现存储、读写功能,还需要对IP核进行实例化操作,FIFO IP核例化代码如下:
//------------------------------------------------//
//spi_fifo
//负责存储SPI通信的数据
//FIFO:先进先出,主要用于缓存数据。
spi_fifo u0(
    .data(receive_byte),
    .wrclk(wrclk),
    .wrreq(wrreq),
    .wrfull(),
 
    .rdclk(rdclk),  
    .rdreq(rdreq),
    .rdempty(),
    .q(data_out)
);
case(rx_state)
	rx_idle_state:begin//空闲状态,匹配伪命令时钟
		rx_state <= rx_judge_state;
	end
	rx_judge_state:begin//接收指令字节,判断指令含义分配跳转状态机状态
		case(receive_byte)	
			8'h01:begin//存储指令编码(获取设备状态)
				order <= receive_byte;
				end
			8'h04:begin
				rx_state <= rx_wr_add_state;
				order <= receive_byte;
				end
			8'h07:begin
				rx_state <= rx_rd_add_state;
				order <= receive_byte;
				end
			default:;
		endcase
	end
 
	rx_wr_add_state:begin//控制写请求信号
		case(rx_cnt)
			8'd0:begin
				rx_cnt <= rx_cnt + 1'd1;
				end
			8'd1:begin
				wrreq_r <= 1'd1;
				end	
		default:begin
				end
		endcase	
	end
 
	rx_rd_add_state:begin//控制读请求信号,通过计数器rd_cnt控制读请求
 
		case(rx_cnt)    //信号的使能状态
			8'd0:begin
				rx_cnt <= rx_cnt + 1'd1;
				end
			8'd1:begin
				rdreq_r <= 1'd1;
				rx_cnt <= rx_cnt + 1'd1;
				rd_cnt <= rd_cnt + 1'd1;
				end	
			8'd2:begin
				if(rd_cnt == 12'd1023)
					begin
						rd_cnt <= 12'd0;	
						rdreq_r <= 1'd1;	
					end									
				else								
					begin
						rd_cnt <= rd_cnt + 1'd1;						
					end
				end
			default:;			
		endcase
	end
endcase

六、 实验步骤及实验结果

图22-14

  1. 将硬件正确连接,如图22-14所示。
  2. 打开putty串口调试工具,打开设备管理器查看对应的端口信息,在putty中打开对应的端口,波特率设置为115200,用于打印串口信息及控制FIFO读写;
  3. 将编写好的FPGA代码进行编译,并下载到开发板中;
  4. 将编写好的ARM代码编译,并下载到开发板中,putty工具中会打印相应的SPI通信相关信息(若想多次测试,查看结果,在putty中输入“test”即可);
  5. 观察实验现象及putty终端打印信息——FPGA_LED闪烁,putty终端打印如图22-15所示。

图22-15

七、 拓展实验

  1. 通过Modelsim观察FIFO读写时序是否和参考时序一致。
  2. 阅读FIFO IP核官方手册,观察IP核参数配置不同对其读写操作的影响。
icore4tx_fpga_22.txt · 最后更改: 2022/04/01 11:39 由 sean