FPGA向SlaveFIFO中写入数据

介绍

FPGA向SlaveFIFO中写入数据_第1张图片
如图可以看到,FPGA端产生批量数据通过SlaveFIFO接口发送到FX3,直到FX3的多个FIFO通道都写满了.然后FX3中的数据可以通过USB3.0口快速的传输给电脑.本篇文章讲述的就是如何按照一定的时序将数据写入Slave FIFO中.

所需工具

开发板:我用的是特权hsc开发板
FX3工具:下载安装可以参考这个网址:https://blog.csdn.net/zhang_ze1234/article/details/99654170

参考代码

好了,准备工作做好之后就可以开始写代码了,本实例使用Verilog 编写

输入输出定义:
module usb_controller(
				input clk,		//100MHz
				input rst_n,	
					//FX3 Slave FIFO接口
				input fx3_flaga,
				input fx3_flagb,	
				input fx3_flagc,	//ctl[9]
				input fx3_flagd,	//ctl[8]
				//output fx3_pclk,		//Slave FIFO同步时钟信号
				output reg fx3_slcs_n,		//Slave FIFO片选信号,低电平有效
				output reg fx3_slwr_n,		//Slave FIFO写使能信号,低电平有效
				output reg fx3_slrd_n,		//Slave FIFO读使能信号,低电平有效
				output reg fx3_sloe_n,		//Slave FIFO输出使能信号,低电平有效
				output reg fx3_pktend_n,	//包结束信号
				output reg[1:0] fx3_a,			//操作FIFO地址
				inout[31:0] fx3_db		//数据
			);

//寄存器和参数定义

reg[9:0] num;		//数据寄存器
reg[3:0] delaycnt;	//计数器
reg[3:0] fxstate;	//状态寄存器
parameter	FXS_REST	= 4'd0;
parameter	FXS_IDLE	= 4'd1;
parameter	FXS_WRIT	= 4'd5;
parameter	FXS_WSOP	= 4'd6;
//定时读写操作状态机
always @(posedge clk or negedge rst_n)
	if(!rst_n) fxstate <= FXS_REST;
	else begin
		case(fxstate)
			FXS_REST: begin
				fxstate <= FXS_IDLE;
			end
			FXS_IDLE: begin
				if( fx3_flaga) fxstate <= FXS_WRIT;	//如果fx_3_flaga为高电平时,Slave FIFO为空,可以写数据
				else fxstate <= FXS_IDLE;
			end	
			FXS_WRIT: begin	
				if(num >= 10'd256) fxstate <= FXS_WSOP;
				else fxstate <= FXS_WRIT;
			end	
			FXS_WSOP: begin
				if(delaycnt >= 4'd4) fxstate <= FXS_IDLE;
				else fxstate <= FXS_WSOP;
			end
			default: fxstate <= FXS_IDLE;
		endcase
	end
//数据计数器,用于产生读写时序
always @(posedge clk or negedge rst_n)
	if(!rst_n) num <= 10'd0;
	else if(fxstate == FXS_WRIT) num <= num+1'b1;	//Slave FIFO写操作
	else num <= 10'd0;
	
	//6个clock的延时计数器
always @(posedge clk or negedge rst_n)
	if(!rst_n) delaycnt <= 4'd0;
	else if(fxstate == FXS_WSOP) delaycnt <= delaycnt+1'b1;
	else delaycnt <= 4'd0;
//FX3 Slave FIFO控制信号时序产生
parameter FX3_ON	= 1'b0;
parameter FX3_OFF	= 1'b1;
	
always @(posedge clk or negedge rst_n)
	if(!rst_n) begin
		fx3_slcs_n <= FX3_OFF;		//Slave FIFO片选信号,低电平有效
		fx3_slwr_n <= FX3_OFF;		//Slave FIFO写使能信号,低电平有效
		fx3_slrd_n <= FX3_OFF;		//Slave FIFO读使能信号,低电平有效
		fx3_sloe_n <= FX3_OFF;		//Slave FIFO输出使能信号,低电平有效
		fx3_pktend_n <= FX3_OFF;	//包结束信号
		fx3_a <= 2'b00;			//操作FIFO地址
	end
	else if(fxstate == FXS_IDLE) begin
		fx3_slcs_n <= FX3_OFF;		//Slave FIFO片选信号,低电平有效
		fx3_slwr_n <= FX3_OFF;		//Slave FIFO写使能信号,低电平有效
		fx3_slrd_n <= FX3_OFF;		//Slave FIFO读使能信号,低电平有效
		fx3_sloe_n <= FX3_OFF;		//Slave FIFO输出使能信号,低电平有效
		fx3_pktend_n <= FX3_OFF;	//包结束信号
		fx3_a <= 2'b00;	//写数据
		end
	else if(fxstate == FXS_WRIT) begin
		if(num == 10'd0) begin	//cs = 0; addr = 2'b00;wr = 0;
			fx3_slcs_n <= FX3_ON;		//Slave FIFO片选信号,低电平有效
			fx3_slwr_n <= FX3_ON;		//Slave FIFO写使能信号,低电平有效
			fx3_slrd_n <= FX3_OFF;		//Slave FIFO读使能信号,低电平有效
			fx3_sloe_n <= FX3_OFF;		//Slave FIFO输出使能信号,低电平有效
			fx3_pktend_n <= FX3_OFF;	//包结束信号
			fx3_a <= 2'b00;			//FIFO读地址			
		end
	else if(num == 10'd255) begin	//fx3_pktend_n =0
			fx3_slcs_n <= FX3_ON;		//Slave FIFO片选信号,低电平有效
			fx3_slwr_n <= FX3_ON;		//Slave FIFO写使能信号,低电平有效
			fx3_slrd_n <= FX3_OFF;		//Slave FIFO读使能信号,低电平有效
			fx3_sloe_n <= FX3_OFF;		//Slave FIFO输出使能信号,低电平有效
			fx3_pktend_n <= FX3_ON;		//包结束信号
			fx3_a <= 2'b00;			//FIFO读地址		
		end		
	else if(num == 10'd256) begin	//cs = 0; addr = 2'b00;
			fx3_slcs_n <= FX3_OFF;		//Slave FIFO片选信号,低电平有效
			fx3_slwr_n <= FX3_OFF;		//Slave FIFO写使能信号,低电平有效
			fx3_slrd_n <= FX3_OFF;		//Slave FIFO读使能信号,低电平有效
			fx3_sloe_n <= FX3_OFF;		//Slave FIFO输出使能信号,低电平有效
			fx3_pktend_n <= FX3_OFF;		//包结束信号
			fx3_a <= 2'b00;			//FIFO读地址		
		end	
	end
else if(fxstate == FXS_WSOP) begin
		fx3_slcs_n <= FX3_OFF;		//Slave FIFO片选信号,低电平有效
		fx3_slwr_n <= FX3_OFF;		//Slave FIFO写使能信号,低电平有效
		fx3_slrd_n <= FX3_OFF;		//Slave FIFO读使能信号,低电平有效
		fx3_sloe_n <= FX3_OFF;		//Slave FIFO输出使能信号,低电平有效
		fx3_pktend_n <= FX3_OFF;	//包结束信号
		fx3_a <= 2'b00;			//操作FIFO地址	
	end
else begin
		fx3_slcs_n <= FX3_OFF;		//Slave FIFO片选信号,低电平有效
		fx3_slwr_n <= FX3_OFF;		//Slave FIFO写使能信号,低电平有效
		fx3_slrd_n <= FX3_OFF;		//Slave FIFO读使能信号,低电平有效
		fx3_sloe_n <= FX3_OFF;		//Slave FIFO输出使能信号,低电平有效
		fx3_pktend_n <= FX3_OFF;	//包结束信号
	end 
产生数据写入Slave FIFO中
reg[31:0] fx3_wdb;	//FX3写数据寄存器

always @(posedge clk or negedge rst_n)
	if(!rst_n) fx3_wdb <= 32'd0;
	else if((fxstate == FXS_WRIT) && (num < 10'd256)) fx3_wdb <= fx3_wdb+1'b1;


assign fx3_db = fx3_wdb;	//FX3数据总线方向控制

到这里代码就写完了,数据已经可以放入Slave FIFO中了
下面我们来解释一下这段代码.

代码解析

该段代码的主要功能是检测FX3的SlaveFIFO是否为空,并且不断的写入数据帧。
功能框图如图所示。FX3读写状态机一旦检测到FX3的SlaveFIFO为空,则进入FX3数据写入的状态,写入新的数据帧到FX3的FIFO中。
FPGA向SlaveFIFO中写入数据_第2张图片
FX3读写状态机的状态迁移图如下
FPGA向SlaveFIFO中写入数据_第3张图片
我们可以看到上电状态为FXS_REST ,随后就进入FXS_IDLE状态,判断SlaveFIFO是否为空,可以写入数据,若可以则进入FXS_WRIT状态写数据到FX3的SlaveFIFO中,接着进入FXS_WSOP状态停留一个时钟周期,最后回到FXS_IDLE状态,如此反复.

你可能感兴趣的:(FPGA)