专栏项目框架介绍

项目整体实现框图

如下图所示,是该项目的整体框图,项目的功能概括为:PC端下发数据文件,FPGA板卡接收数据文件,缓存至DDR中,待数据文件发送完毕,循环读取DDR有效写区域数据,将DDR数据同步到SFP时钟域,进行光纤传输,该项目中,涉及UDP协议栈、位宽转换、跨时钟、AXI读写DDR、gt收发器配置、同步码对齐等一系列操作,笔者会就框图中实现的功能做每一步介绍,最终实现整体功能,仿真与上板双重检验,确保代码的稳定。

UDP协议栈的实现,在笔者的FPGA实现UDP协议栈专栏中,已进行详细介绍,在本专栏中,便不再进行赘述,感兴趣的读者可以到下面这个链接学习
FPGA实现UDP协议栈

下面笔者就框图中所示的模块做介绍,其中有些小模块,在此框图中,笔者并未进行绘出,在下面文字中,会进行详细描述,给各位读者展现一个详细的数据流转过程。

项目功能模块介绍

  • UDP协议栈
    该模块实现与上位机通信,包含ping功能实现,与用户的交互接口定义为AXIS总线,可进行的位宽为8bit的udp报文上传与udp报文接收。

其模块接口如下

c 复制代码
module udp_module(
    input                   i_rxc           ,
    input   [3 :0]          i_rxd           ,
    input                   i_rx_ctl        ,
    output                  o_txc           ,
    output  [3 :0]          o_txd           ,
    output                  o_tx_ctl        ,
    output                  o_udp_clk       ,
    output                  o_udp_rst       ,
    output  [15:0]          o_rec_len       ,
    output  [7 :0]          o_rec_data      ,
    output                  o_rec_last      ,
    output                  o_rec_valid
);

因为在本项目中,暂时不涉及udp报文的上传,故在本级模块中,未将输出数据接口引出,而是直接将接收到的数据传输至上位机,进行报文丢失校验。

  • udp命令检测与数据输出
    该模块进行DDR擦除与数据文件传输完毕的命令检测,以及有效数据的输出,避免命令数据缓存至DDR,造成数据错误。
    其模块接口如下
    输入为UDP报文,输出为DDR擦除,存储完毕,有效数据,运行在UDP时钟域
c 复制代码
module udp_cmd_check(
    input               i_clk           ,
    input               i_rst           ,
    input   [7 :0]      i_udp_data      ,
    input               i_udp_valid     ,
    output  [7 :0]      o_udp_data      ,
    output              o_udp_valid     ,
    output              o_store_done    ,
    output              o_raddr_clear   
    );
  • 数据位宽转换与跨时钟处理
    该模块主要实现将1Byte数据(UDP时钟域)转换为4Bytes数据(DDR时钟域)
    其模块接口如下
    输入为check后的udp报文,输出为DDR时钟域写入数据
c 复制代码
module ASYNC_BUF_DDR(
    input               i_udp_clk   ,
    input               i_udp_rst   ,
    input               i_ui_clk    ,
    input               i_ui_rst    ,
    input   [7 :0]      i_udp_data  ,
    input               i_udp_valid ,
    output  [31:0]      o_send_data ,
    output              o_send_valid
    );
  • ddr读写控制模块
    该模块主要实现功能:接收异步处理后的4Bytes数据,传输至DDR的AXI控制器,以及接收来自DDR的AXI控制器输出的读数据
    其模块接口如下:
c 复制代码
module ddr_rw_control(
    input               i_ui_clk        ,
    input               i_ui_rst        ,
    /*ASYNC_BUF_DDR*/
    input   [31:0]      i_send_data     ,
    input               i_send_valid    ,
    input               i_read_cmd      ,
    input               i_raddr_clear   ,
    input               i_read_back     ,
    output  [15:0]      o_store_size    ,
    /*op-->axi*/
    output  [1 :0]      o_op_cmd        ,
    output  [29:0]      o_op_waddr      ,
    output  [29:0]      o_op_raddr      ,
    output              o_op_valid      ,
    input               i_op_ready      ,
    output  [31:0]      o_write_data    ,
    output              o_write_valid   ,
    input   [31:0]      i_read_data     ,
    input               i_read_valid    
    );

--内存读取控制器

该模块主要功能为:接收数据报文传输完成以及数据擦除指令,进行DDR数据的循环读取,并将读取到的数据转换至SFP时钟域,传输给光纤模块。

其模块接口如下:

c 复制代码
module read_memory_ctrl(
    input               i_ui_clk        ,
    input               i_ui_rst        ,
    input               i_sfp_clk       ,
    input               i_sfp_rst       ,
    input               i_store_done    ,
    input   [15:0]      i_store_size    ,
    input               i_raddr_clear   ,
    output              o_read_back     ,
    output              o_read_cmd      ,
    input   [31:0]      i_read_data     ,
    input               i_read_valid    ,
    output  [31:0]      o_sfp_data      ,
    output              o_sfp_valid     
    );
  • ddr axi读写驱动
    该模块主要功能为:接收数据读写op指令,将将其转换为AXI4总线形式,进行数据写入与读取
    其模块接口如下
c 复制代码
module ddr_axi_rw#(
    parameter           C_M_TARGET_SLAVE_BASE_ADDR	= 32'h00000000  ,
	parameter   integer C_M_AXI_BURST_LEN	        = 256           ,
	parameter   integer C_M_AXI_ID_WIDTH	        = 1             ,
	parameter   integer C_M_AXI_ADDR_WIDTH	        = 30            ,
	parameter   integer C_M_AXI_DATA_WIDTH	        = 32            ,
	parameter   integer C_M_AXI_AWUSER_WIDTH        = 0             ,
	parameter   integer C_M_AXI_ARUSER_WIDTH        = 0             ,
	parameter   integer C_M_AXI_WUSER_WIDTH	        = 0             ,
	parameter   integer C_M_AXI_RUSER_WIDTH	        = 0             ,
	parameter   integer C_M_AXI_BUSER_WIDTH	        = 0
)(
    input                                   init_calib_complete ,
    input   [1 :0]                          i_op_cmd            ,
    input   [29:0]                          i_op_waddr          ,
    input   [29:0]                          i_op_raddr          ,
    input                                   i_op_valid          ,
    output                                  o_op_ready          ,
    input   [31:0]                          i_write_data        ,
    input                                   i_write_valid       ,
    output  [31:0]                          o_read_data         ,
    output                                  o_read_valid        ,

    input									M_AXI_ACLK          ,
	input									M_AXI_ARESETN       ,
	output	[C_M_AXI_ID_WIDTH-1 :0]    		M_AXI_AWID          ,
	output	[C_M_AXI_ADDR_WIDTH-1 :0]  		M_AXI_AWADDR        ,
	output	[7 :0]                     		M_AXI_AWLEN         ,
	output	[2 :0]                     		M_AXI_AWSIZE        ,
	output	[1 :0]                     		M_AXI_AWBURST       ,
	output	                            	M_AXI_AWLOCK        ,
	output	[3 :0]                     		M_AXI_AWCACHE       ,
	output	[2 :0]                     		M_AXI_AWPROT        ,
	output	[3 :0]                     		M_AXI_AWQOS         ,
	output	[C_M_AXI_AWUSER_WIDTH-1 :0]		M_AXI_AWUSER        ,
	output	                            	M_AXI_AWVALID       ,
	input 	                            	M_AXI_AWREADY       ,
	output	[C_M_AXI_DATA_WIDTH-1 :0]  		M_AXI_WDATA         ,
	output	[C_M_AXI_DATA_WIDTH/8-1 :0]		M_AXI_WSTRB         ,
	output	                            	M_AXI_WLAST         ,
	output	[C_M_AXI_WUSER_WIDTH-1 :0] 		M_AXI_WUSER         ,
	output	                            	M_AXI_WVALID        ,
	input 	                            	M_AXI_WREADY        ,
	input 	[C_M_AXI_ID_WIDTH-1 :0]       	M_AXI_BID           ,
	input 	[1 :0]                        	M_AXI_BRESP         ,
	input 	[C_M_AXI_BUSER_WIDTH-1 :0]    	M_AXI_BUSER         ,
	input 	                               	M_AXI_BVALID        ,
	output	                               	M_AXI_BREADY        , 
    output  [C_M_AXI_ID_WIDTH-1 :0]         M_AXI_ARID          ,
    output  [C_M_AXI_ADDR_WIDTH-1 :0]       M_AXI_ARADDR        ,
    output  [7 :0]                          M_AXI_ARLEN         ,
    output  [2 :0]                          M_AXI_ARSIZE        ,
    output  [1 :0]                          M_AXI_ARBURST       ,
    output                                  M_AXI_ARLOCK        ,
    output  [3 : 0]                         M_AXI_ARCACHE       ,
    output  [2 : 0]                         M_AXI_ARPROT        ,
    output  [3 : 0]                         M_AXI_ARQOS         ,
    output  [C_M_AXI_ARUSER_WIDTH-1 :0]     M_AXI_ARUSER        ,
    output                                  M_AXI_ARVALID       ,
    input                                   M_AXI_ARREADY       ,
    input   [C_M_AXI_ID_WIDTH-1 :0]         M_AXI_RID           ,
    input   [C_M_AXI_DATA_WIDTH-1 :0]       M_AXI_RDATA         ,
    input   [1: 0]                          M_AXI_RRESP         ,
    input                                   M_AXI_RLAST         ,
    input   [C_M_AXI_RUSER_WIDTH-1 :0]      M_AXI_RUSER         ,
    input                                   M_AXI_RVALID        ,
    output                                  M_AXI_RREADY         
    );

该模块与mig ddr3 ip一齐被例化在ddr_top模块

c 复制代码
module ddr_top(
    input               i_ddr_clk       ,
    input               i_ddr_rstn      ,
    output  [14:0]      ddr3_addr       ,
    output  [2 :0]      ddr3_ba         ,
    output		        ddr3_cas_n      ,
    output  [0 :0]      ddr3_ck_n       ,
    output  [0 :0]      ddr3_ck_p       ,
    output  [0 :0]      ddr3_cke        ,
    output		        ddr3_ras_n      ,
    output			    ddr3_reset_n    ,
    output			    ddr3_we_n       ,
    inout   [31:0]		ddr3_dq         ,
    inout   [3 :0]		ddr3_dqs_n      ,
    inout   [3 :0]		ddr3_dqs_p      ,
    output  [0 :0]		ddr3_cs_n       ,
    output  [3 :0]		ddr3_dm         ,
    output  [0 :0]		ddr3_odt        ,

    output              ui_clk          ,
    output              ui_clk_sync_rst ,
    input   [1 :0]      i_op_cmd        ,
    input   [29:0]      i_op_waddr      ,
    input   [29:0]      i_op_raddr      ,
    input               i_op_valid      ,
    output              o_op_ready      ,
    input   [31:0]      i_write_data    ,
    input               i_write_valid   ,
    output  [31:0]      o_read_data     ,
    output              o_read_valid    
    );
  • 光纤传输器
    该模块主要功能为接收从DDR读取的数据(同步至SFP时钟域),进行帧头,进行帧尾封装,传输数据
    其模块接口如下:
c 复制代码
gt_one_top gt_one_top_u0(
    .i_sysclk            (w_sys_clk         ),
    .i_gtrefclk_p        (i_gtrefclk_p      ),
    .i_gtrefclk_n        (i_gtrefclk_n      ),
    .o_gt_tx_p           (o_gt_tx_p         ),
    .o_gt_tx_n           (o_gt_tx_n         ),
    .i_gt_rx_p           (i_gt_rx_p         ),
    .i_gt_rx_n           (i_gt_rx_n         ),
    .o_sfp_disable       (o_sfp_disable     ),
    .o_sfp_txclk         (w_sfp_clk         ),
    .o_sfp_txrst         (w_sfp_rst         ),
    .i_send_data         (w_sfp_data        ),
    .i_send_valid        (w_sfp_valid       )
    );
相关推荐
麻雀无能为力8 分钟前
git的使用
git
碎碎思44 分钟前
FPGA+ESP32 = GameBoy 是你的童年吗?
fpga开发
搬砖的小码农_Sky2 小时前
FPGA:XILINX FPGA产品线以及器件选型建议
嵌入式硬件·fpga开发·硬件架构·硬件工程
YprgDay2 小时前
【Lattice FPGA 开发】Diamond在线调试Reveal逻辑乱跳的解决
fpga开发·diamond·reveal
MVP-curry-萌神2 小时前
FPGA图像处理(六)------ 图像腐蚀and图像膨胀
图像处理·人工智能·fpga开发
算法歌者3 小时前
Visual Studio 项目 .gitignore 文件指南
git·visual studio
江边垂钓者3 小时前
git cherry-pick和git stash命令详解
git
Lw老王要学习3 小时前
Linux架构篇、第五章git2.49.0部署与使用
linux·运维·git·云计算·it
&Cheems3 小时前
ZYNQ笔记(二十):Clocking Wizard 动态配置
笔记·fpga开发
怪小庄吖3 小时前
7系列 之 I/O标准和终端技术
经验分享·笔记·fpga开发·硬件架构·硬件工程·xilinx 7系列 fpga·i/o标准和终端技术