您当前的位置: 首页 >  udp

9527华安

暂无认证

  • 3浏览

    0关注

    35博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

FPGA实现UDP通信,UDP环通测试还行

9527华安 发布时间:2022-06-28 14:40:02 ,浏览量:3

最近看了很多UDP的资料,也参考并实现了很多种方案,但总觉得不完美,有轻量级的UDP方案,但不支持ping功能,这种也能实现UDP通信,但在工程上等同于废物,试想,多点通信时一旦不同,如果ping功能都没有,来怎么排查?所以这种方案直接被pass;其次,也有支持ping功能的方案,但实现过于复杂,时序也够复杂,且不适合大批量数据传输,比如opencorese上面的;其实关于UDP网络通信,Xilinx是有自己的方案的,但只给到了rgmii转gmii这一层,并给出了三速网IP,将rgmii转为axis用户接口的gmii,但并没有给出完整UDP封装的IP核,这一点给了米联客机会,米联客推出了自己的UDP协议栈,用于对接Xilinx的三速网IP,从而解决了改问题,但该UDP协议栈只是网表文件,并未给出源码。 根据官方手册,封装了的UDP协议栈用户接口发送时序如下: 在这里插入图片描述 首先等待udp_tx_ready为高,然后拉高app_tx_request信号,并等待UDP应答信号app_tx_ack,若app_tx_ack为高,则拉高app_tx_data_valid并给出发送数据app_tx_data、发送长度app_tx_data_length以及app_tx_data_keep,并在数据包的最后一个数据拉高app_tx_data_last; 需要注意的是,在一包数据期间,app_tx_data_valid必须持续为高,如果不需要数据屏蔽,app_tx_data_keep移植保持0xff; 接收时序如下: 接收就简单多了,app_rx_data_valid为高期间接收app_rx_data就可以了,当app_rx_data_last拉高时表明数据接收完毕,同时也给出了发送的数据长度app_rx_data_length。 在这里插入图片描述 协议栈总体框图如下: 在这里插入图片描述 实现流程如下图: 在这里插入图片描述 Tri_mode_ethernet_mac配置为千兆网,若依时钟是125M,用户接口是8bit的axis接口,而协议栈的用户接口是64bit的,所以对于传单个数据而言,协议栈一侧的时钟应=125X8÷64=15.625M,通过其中1个FIFO实现异步时钟域的转换,1个FIFO实现数 据缓冲和同步Packet mode功能。 Packet mode 是指 FIFO 在输出数据前持续缓存 AXI-Stream 接口输入的数据直至输入端 tlast 信号拉高, 即存满一个完整的数据包时,才开始在 AXI-Stream 输出端口向外输出数据。Packet mode 功能设置如下图所 示。需要注意的是,启用 Packet mode 时,FIFO 必须工作于同步模式。 对于发送路径,启用 Packet mode 是为了防止 FIFO 被 IP 核读空。对于接收路径,是由于米联的 UDP IP 协议栈要求 1 个数据包的 tvalid 信号在数据包持续期间必须恒为 1。 在这里插入图片描述 环通测试的波形如下,与官方手册一致。 在这里插入图片描述 测试代码如下:

module udp_loop_test(
	input  		 reset			 ,
	input  		 dcm_locked      ,
	input  		 refclk_200m     ,
	input  		 udp_clk_15_625m ,
	input  		 gtx_clk_125m    ,
	input  		 rgmii_rxc   	 ,
	input  		 rgmii_rx_ctl    ,
	input  [3:0] rgmii_rxd	     ,
	output 		 rgmii_txc   	 ,  	
	output 		 rgmii_tx_ctl	 ,
	output [3:0] rgmii_txd         	
);
	
(* MARK_DEBUG="true" *) wire core_reset					;
(* MARK_DEBUG="true" *) wire udp_tx_ready	            ;
(* MARK_DEBUG="true" *) wire app_tx_ack                 ;
(* MARK_DEBUG="true" *) wire [63:0] app_tx_data         ;

(* MARK_DEBUG="true" *) wire dst_ip_unreachable         ;
(* MARK_DEBUG="true" *) wire app_rx_data_valid          ;
(* MARK_DEBUG="true" *) wire [63:0] app_rx_data         ;
(* MARK_DEBUG="true" *) wire [15:0] app_rx_data_length  ;
(* MARK_DEBUG="true" *) wire udp_rx_error               ;
(* MARK_DEBUG="true" *) wire ip_rx_error	            ;
(* MARK_DEBUG="true" *) wire [8:0] fifo_data_count      ;

(* MARK_DEBUG="true" *) reg  app_tx_request             ;
(* MARK_DEBUG="true" *) reg  app_tx_data_valid          ;
(* MARK_DEBUG="true" *) reg  app_tx_data_last           ;
(* MARK_DEBUG="true" *) reg  [15:0] app_tx_data_length  ;
(* MARK_DEBUG="true" *) reg  [7: 0] app_tx_data_keep    ;
(* MARK_DEBUG="true" *) reg  rd_en                      ;
(* MARK_DEBUG="true" *) reg  [3:0] ST                   ;
(* MARK_DEBUG="true" *) reg  [15:0] udp_tx_length       ;

always @(posedge udp_clk_15_625m) begin
	if(core_reset) begin
		app_tx_request 	              
关注
打赏
1659431378
查看更多评论
0.0368s