基于FPGA的APS6404L-3SQR QSPI PSRAM驱动设计(2)

1.摘要

上一篇文章 基于FPGA的APS6404L-3SQR QSPI PSRAM驱动设计(1)主要记录了数据手册和设计中框架,这里记录一下具体的spi协议相关的设计。

在PSRAM的众多命令中有一些命令用spi协议控制更方便(我感觉)。比如两个复位命令66和99,在没配置QPI命令模式之前只能用SPI协议,所以类似复位命令这些指令如(良品检测、配置QPI和边界选择)都使用SPI来控制即可。

这些协议中除了良品检测命令其他都只是需要简单发送8bit命令,利用spi协议发送简单的一批。对于良品检测命令就需要用到状态机控制了,分别写命令+写地址+读数据了,稍微复杂一点。

2.FPGA设计

2.1、时序图设计

当spi模块的状态机跳转到写命令状态时,即可开始向PSRAM芯片写入命令,具体工作过程如时序图所示:

具体设计思路为:

状态机检测到命令输入立刻从IDLE跳转到SPI_CMD,同时spi工作有效信号r_run拉高。因为是8bit命令,所以计数器r_cnt计数0-7,r_spi_cnt作为计数器标志信号,通过在spi有效期内翻转实现,也就是二分频,同时也作为o_spi_clk。

当输入的命令为良品检测时,r_run信号将延迟拉低,具体时间为24bit的地址周期,加上56bit的读数据周期,最终当 r_cnt计数到88时在拉低,其余信号逻辑不变。

代码中的i_spi_8bit_cmd信号是上层模块输入的判断是否是良品检测命令,不是为1是为0。

复制代码
always@(*)
begin
	if(i_rst)
		r_spi_fsm_next	<=	'd0	;
	else begin
		case (r_spi_fsm_current)
			IDLE		:	
				if (w_user_active)	begin
					r_spi_fsm_next	<=	SPI_CMD	;
				end else 
					r_spi_fsm_next	<=	IDLE	;
			SPI_CMD		:
				if (r_cnt == 'd7 && r_spi_cnt)
					if (i_spi_8bit_cmd)
						r_spi_fsm_next	<=	SPI_END	;
					else 
						r_spi_fsm_next	<=	SPI_ADDR	;
				else 
					r_spi_fsm_next	<=	SPI_CMD		;
			SPI_ADDR	:
				if (r_cnt == 'd23 && r_spi_cnt)
					r_spi_fsm_next	<=	SPI_DATA	;
				else 
					r_spi_fsm_next	<=	SPI_ADDR	;
			SPI_DATA	:
				if (r_cnt == 'd55 && r_spi_cnt)
					r_spi_fsm_next	<=	SPI_END	;
				else 
					r_spi_fsm_next	<=	SPI_DATA	;
			SPI_END		:
				r_spi_fsm_next	<=	IDLE	;
			default		:
				r_spi_fsm_next	<=	IDLE	;
		endcase 
	end 
end 

always@(posedge i_clk,posedge i_rst)
begin
	if(i_rst)	
		r_run <= 'd0;
	else if (r_spi_fsm_current == SPI_CMD && i_spi_8bit_cmd)	begin
		if (r_spi_cnt && r_cnt == 'd7)
			r_run 	<=	1'b0;
		else 
			r_run	<=	1'b1;
	end else if (r_spi_fsm_current == SPI_DATA && r_run)	begin
		if (r_spi_cnt && r_cnt == 'd55)
			r_run	<=	1'b0	;
		else 
			r_run	<=	1'b1	;
	end else if(w_user_active)
		r_run <= 'd1;
	else 
		r_run <= r_run;
end

always@(posedge i_clk,posedge i_rst)
begin
	if(i_rst)
		r_cnt	<=	'd0	;
	else if (r_spi_fsm_current != r_spi_fsm_next)
		r_cnt <= 'd0;
	else if (r_run && r_spi_cnt)	
		r_cnt	<=	r_cnt + 'd1	;
end 

always@(posedge i_clk,posedge i_rst)
begin
	if(i_rst)
		r_spi_cnt <= 'd0;
	else if(r_run)
		r_spi_cnt <= r_spi_cnt + 1;
	else 
		r_spi_cnt <= 'd0;
end

对于6线spi芯片来说,它的数据线是inout接口,所以需要添加控制信号来判断是输入还是输出。如下代码,输出一下信号用于上层模块判断。

复制代码
(* PAP_MARK_DEBUG="1" *)wire    cmd_flag		=	(r_spi_fsm_current == SPI_CMD);
(* PAP_MARK_DEBUG="1" *)wire    addr_flag	=	(r_spi_fsm_current == SPI_ADDR);
(* PAP_MARK_DEBUG="1" *)wire    data_flag	=	(r_spi_fsm_current == SPI_DATA);

spi驱动模块的所有端口信号如下:

复制代码
spi_drive#(
    parameter               P_DATA_WIDTH        	= 8 ,
							P_ADDR_WIDTH		= 24,
							P_READ_DATA_WIDTH   	= 8 , 
							P_CPOL              	= 0 ,
							P_CPHL              	= 0 
)(                  
	input	wire					i_clk               ,
	input	wire					i_rst               ,

	output	wire					o_spi_clk           ,
	output	wire					o_spi_cs            ,
	
	input	wire					i_spi_mosi		,
	output 	wire					o_spi_miso		,
	output 	wire					o_spi_cmd_flag	,
	output 	wire					o_spi_addr_flag	,
	output 	wire					o_spi_data_flag	,

	input	wire					i_spi_8bit_cmd	,

	input	wire	[23:0]			i_user_addr			,
	input	wire	[7 :0]   		i_user_cmd        ,
	input	wire					i_user_valid        ,
	output	wire					o_user_ready        ,

    output	wire	[7:0]   		o_user_read_data    ,
    output	wire                    o_user_read_valid   
);

对于读取PSRAM读取良品检测输出信号,按照时序图我们需要在读数据阶段读到的第二个字节数据作为良品与否的判断。所以当r_cnt计数到15切r_qpi_cnt为1的时候获取读到的值。具体代码如下:

复制代码
always@(posedge ro_spi_clk,posedge i_rst)
begin
	if(i_rst)
		ro_user_read_data <= 'd0;
	else	if (data_flag)
		ro_user_read_data <= {ro_user_read_data[P_DATA_WIDTH - 2 : 0],i_spi_mosi};
	else 
		ro_user_read_data <= 'd0;
end

always@(posedge i_clk,posedge i_rst) 
begin
	if(i_rst)
		ro_user_read_valid <= 'd0;
	else if (r_spi_fsm_current == SPI_DATA && ((r_cnt == 'd7 || r_cnt == 'd15) && r_spi_cnt))
		ro_user_read_valid <= 'd1;
	else 
		ro_user_read_valid <= 'd0;
end

3.上板验证

按照时序图,关于spi驱动部分正确输出良品检测通过指令8'H5D。

相关推荐
unicrom_深圳市由你创科技4 小时前
板上调试,先抓哪些信号?排查顺序是什么?
fpga开发
北城笑笑6 小时前
FPGA 55 ,FPGA 行业 2026 发展分析与报告
fpga开发·fpga
Jason_zhao_MR7 小时前
新一代电能数据采集终端方案
linux·人工智能·嵌入式硬件·fpga开发·嵌入式
ERROR:991 天前
AMD Ross没有介入Vivado的私生活
fpga开发
Riwuarua1 天前
从近似 0 基础开始 FPGA 开发——Part.18:FPGA 复位系统与可靠启动设计
fpga开发
智感子3 天前
测控链路:从传感器到上位机
人工智能·嵌入式硬件·fpga开发
szxinmai主板定制专家3 天前
基于Zynq的高精度多通道数据采集卡完整解决方案(工业振动/高速采集/边缘传输)
fpga开发·zynq·数据采集卡
szxinmai主板定制专家3 天前
基于TI AM62x+FPGA的24bit高精度数据采集卡设计(振动/风电/发动机监测)
人工智能·fpga开发·arm+fpga·rk3588+fpga
szxinmai主板定制专家3 天前
基于 ARM+FPGA 雕刻机控制系统的设计
arm开发·人工智能·fpga开发·rk3576·半导体设备
吉他英雄一里4 天前
zynq入门教程
fpga开发·zynq