项目整体实现框图
如下图所示,是该项目的整体框图,项目的功能概括为: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 )
);