基于xilinx k7 325t实现的千兆网udp协议只需要设置好IP端口就可以直接给数据基本等同于透传可以不用管底层协议。 可以 # FPGA 实现udp模块说明 ## udp_protocol_top gig_ethernet_pcs_pma有脚本生成,任何版本vivado都可以支持,注释里面有对重要信号的说明,默认是1000M,100M需要改内部信号,PHY芯片是88E1512SGMII接口。 FPGA和上位机IP端口都要设置好才能收到数据注意在同一个网段 ## 接收数据 udp_protocol_top.rx_udp_payload_axis_tvalid拉高的时候就代表udp_protocol_top.rx_udp_payload_axis_tdata有效,udp_protocol_top.rx_udp_payload_axis_tready默认给1可以一直收数据 ## 发送数据 tx_udp_payload_axis_tready1的时候拉高tx_udp_payload_axis_tvalid,数据才有效发送完成以后一定要发送一个tx_udp_payload_axis_tlast脉冲指示最后一个数据最近在项目中基于 Xilinx K7 325t 完成了千兆网 UDP 协议的相关实现感觉挺有意思来和大家分享下。这个实现基本就像是透传一样只要设置好 IP 和端口就能直接给数据底层协议不用我们太操心。FPGA 实现 udp 模块说明udp_protocol_top这里面的 gigethernetpcs_pma 是通过脚本生成的而且不管啥版本的 Vivado 都能支持它这点还是挺方便的。在代码注释里对重要信号都有说明默认情况下是 1000M 的速率如果要改成 100M 的话就得改改内部信号。这里用的 PHY 芯片是 88E1512采用的是 SGMII 接口。在实际应用中FPGA 和上位机的 IP 以及端口都得设置好而且要注意在同一个网段不然数据可收不到哦。基于xilinx k7 325t实现的千兆网udp协议只需要设置好IP端口就可以直接给数据基本等同于透传可以不用管底层协议。 可以 # FPGA 实现udp模块说明 ## udp_protocol_top gig_ethernet_pcs_pma有脚本生成,任何版本vivado都可以支持,注释里面有对重要信号的说明,默认是1000M,100M需要改内部信号,PHY芯片是88E1512SGMII接口。 FPGA和上位机IP端口都要设置好才能收到数据注意在同一个网段 ## 接收数据 udp_protocol_top.rx_udp_payload_axis_tvalid拉高的时候就代表udp_protocol_top.rx_udp_payload_axis_tdata有效,udp_protocol_top.rx_udp_payload_axis_tready默认给1可以一直收数据 ## 发送数据 tx_udp_payload_axis_tready1的时候拉高tx_udp_payload_axis_tvalid,数据才有效发送完成以后一定要发送一个tx_udp_payload_axis_tlast脉冲指示最后一个数据下面简单看一下代码结构这里只是示意非完整代码module udp_protocol_top ( // 各种信号声明 input wire clk, input wire rst, // 与千兆网相关信号 wire [31:0] gig_ethernet_pcs_pma_sig, // 接收数据相关信号 output wire rx_udp_payload_axis_tvalid, output wire [63:0] rx_udp_payload_axis_tdata, input wire rx_udp_payload_axis_tready, // 发送数据相关信号 input wire tx_udp_payload_axis_tvalid, input wire [63:0] tx_udp_payload_axis_tdata, output wire tx_udp_payload_axis_tready, output wire tx_udp_payload_axis_tlast ); // 这里面会实例化 gig_ethernet_pcs_pma 模块 gig_ethernet_pcs_pma #( .PARAM1(VALUE1), .PARAM2(VALUE2) ) u_gig_ethernet_pcs_pma ( .clk(clk), .rst(rst), .sig(gig_ethernet_pcs_pma_sig) ); // 其他逻辑代码比如数据处理UDP 协议相关逻辑等 endmodule这里面gigethernetpcspma模块负责和千兆网物理层相关的处理而udpprotocol_top模块则在这个基础上完成 UDP 协议相关的数据收发等功能。接收数据在接收数据的时候当udpprotocoltop.rxudppayloadaxistvalid拉高就意味着udpprotocoltop.rxudppayloadaxistdata里面的数据是有效的。而udpprotocoltop.rxudppayloadaxistready这个信号默认给 1 的话就能一直接收数据啦。从代码逻辑上看就像下面这样always (posedge clk or posedge rst) begin if (rst) begin // 复位相关信号 end else begin if (rx_udp_payload_axis_tvalid rx_udp_payload_axis_tready) begin // 处理接收到的数据比如存入缓存等操作 received_data rx_udp_payload_axis_tdata; end end end上面这段代码就是当接收数据有效且接收准备好的时候把接收到的数据存到received_data这个变量里实际应用可能会更复杂比如存入 FIFO 等。发送数据发送数据也有讲究当txudppayloadaxistready 1的时候拉高txudppayloadaxistvalid这时的数据才有效。而且在发送完成以后一定要发送一个txudppayloadaxistlast脉冲来指示这是最后一个数据。看下面这段代码示例reg [63:0] data_to_send; reg send_data; always (posedge clk or posedge rst) begin if (rst) begin send_data 0; end else begin if (some_condition) begin // 这里 some_condition 代表发送数据的条件比如缓存有数据等 send_data 1; data_to_send some_data; // some_data 是要发送的数据 end end end always (posedge clk or posedge rst) begin if (rst) begin tx_udp_payload_axis_tvalid 0; tx_udp_payload_axis_tlast 0; end else begin if (send_data tx_udp_payload_axis_tready) begin tx_udp_payload_axis_tvalid 1; tx_udp_payload_axis_tdata data_to_send; if (is_last_data) begin // is_last_data 代表是否是最后一个数据的判断 tx_udp_payload_axis_tlast 1; end end else begin tx_udp_payload_axis_tvalid 0; tx_udp_payload_axis_tlast 0; end end end在这段代码里当满足发送条件somecondition时准备好要发送的数据datatosend并拉高senddata。然后当txudppayloadaxistready为 1 时发送数据并在判断是最后一个数据时拉高txudppayloadaxistlast。总的来说基于 Xilinx K7 325t 实现的这个千兆网 UDP 协议模块虽然功能类似透传但在数据收发的细节处理上还是有不少需要注意的地方希望我的这些分享能给大家带来一些帮助和启发。
基于 Xilinx K7 325t 的千兆网 UDP 协议实现小记
基于xilinx k7 325t实现的千兆网udp协议只需要设置好IP端口就可以直接给数据基本等同于透传可以不用管底层协议。 可以 # FPGA 实现udp模块说明 ## udp_protocol_top gig_ethernet_pcs_pma有脚本生成,任何版本vivado都可以支持,注释里面有对重要信号的说明,默认是1000M,100M需要改内部信号,PHY芯片是88E1512SGMII接口。 FPGA和上位机IP端口都要设置好才能收到数据注意在同一个网段 ## 接收数据 udp_protocol_top.rx_udp_payload_axis_tvalid拉高的时候就代表udp_protocol_top.rx_udp_payload_axis_tdata有效,udp_protocol_top.rx_udp_payload_axis_tready默认给1可以一直收数据 ## 发送数据 tx_udp_payload_axis_tready1的时候拉高tx_udp_payload_axis_tvalid,数据才有效发送完成以后一定要发送一个tx_udp_payload_axis_tlast脉冲指示最后一个数据最近在项目中基于 Xilinx K7 325t 完成了千兆网 UDP 协议的相关实现感觉挺有意思来和大家分享下。这个实现基本就像是透传一样只要设置好 IP 和端口就能直接给数据底层协议不用我们太操心。FPGA 实现 udp 模块说明udp_protocol_top这里面的 gigethernetpcs_pma 是通过脚本生成的而且不管啥版本的 Vivado 都能支持它这点还是挺方便的。在代码注释里对重要信号都有说明默认情况下是 1000M 的速率如果要改成 100M 的话就得改改内部信号。这里用的 PHY 芯片是 88E1512采用的是 SGMII 接口。在实际应用中FPGA 和上位机的 IP 以及端口都得设置好而且要注意在同一个网段不然数据可收不到哦。基于xilinx k7 325t实现的千兆网udp协议只需要设置好IP端口就可以直接给数据基本等同于透传可以不用管底层协议。 可以 # FPGA 实现udp模块说明 ## udp_protocol_top gig_ethernet_pcs_pma有脚本生成,任何版本vivado都可以支持,注释里面有对重要信号的说明,默认是1000M,100M需要改内部信号,PHY芯片是88E1512SGMII接口。 FPGA和上位机IP端口都要设置好才能收到数据注意在同一个网段 ## 接收数据 udp_protocol_top.rx_udp_payload_axis_tvalid拉高的时候就代表udp_protocol_top.rx_udp_payload_axis_tdata有效,udp_protocol_top.rx_udp_payload_axis_tready默认给1可以一直收数据 ## 发送数据 tx_udp_payload_axis_tready1的时候拉高tx_udp_payload_axis_tvalid,数据才有效发送完成以后一定要发送一个tx_udp_payload_axis_tlast脉冲指示最后一个数据下面简单看一下代码结构这里只是示意非完整代码module udp_protocol_top ( // 各种信号声明 input wire clk, input wire rst, // 与千兆网相关信号 wire [31:0] gig_ethernet_pcs_pma_sig, // 接收数据相关信号 output wire rx_udp_payload_axis_tvalid, output wire [63:0] rx_udp_payload_axis_tdata, input wire rx_udp_payload_axis_tready, // 发送数据相关信号 input wire tx_udp_payload_axis_tvalid, input wire [63:0] tx_udp_payload_axis_tdata, output wire tx_udp_payload_axis_tready, output wire tx_udp_payload_axis_tlast ); // 这里面会实例化 gig_ethernet_pcs_pma 模块 gig_ethernet_pcs_pma #( .PARAM1(VALUE1), .PARAM2(VALUE2) ) u_gig_ethernet_pcs_pma ( .clk(clk), .rst(rst), .sig(gig_ethernet_pcs_pma_sig) ); // 其他逻辑代码比如数据处理UDP 协议相关逻辑等 endmodule这里面gigethernetpcspma模块负责和千兆网物理层相关的处理而udpprotocol_top模块则在这个基础上完成 UDP 协议相关的数据收发等功能。接收数据在接收数据的时候当udpprotocoltop.rxudppayloadaxistvalid拉高就意味着udpprotocoltop.rxudppayloadaxistdata里面的数据是有效的。而udpprotocoltop.rxudppayloadaxistready这个信号默认给 1 的话就能一直接收数据啦。从代码逻辑上看就像下面这样always (posedge clk or posedge rst) begin if (rst) begin // 复位相关信号 end else begin if (rx_udp_payload_axis_tvalid rx_udp_payload_axis_tready) begin // 处理接收到的数据比如存入缓存等操作 received_data rx_udp_payload_axis_tdata; end end end上面这段代码就是当接收数据有效且接收准备好的时候把接收到的数据存到received_data这个变量里实际应用可能会更复杂比如存入 FIFO 等。发送数据发送数据也有讲究当txudppayloadaxistready 1的时候拉高txudppayloadaxistvalid这时的数据才有效。而且在发送完成以后一定要发送一个txudppayloadaxistlast脉冲来指示这是最后一个数据。看下面这段代码示例reg [63:0] data_to_send; reg send_data; always (posedge clk or posedge rst) begin if (rst) begin send_data 0; end else begin if (some_condition) begin // 这里 some_condition 代表发送数据的条件比如缓存有数据等 send_data 1; data_to_send some_data; // some_data 是要发送的数据 end end end always (posedge clk or posedge rst) begin if (rst) begin tx_udp_payload_axis_tvalid 0; tx_udp_payload_axis_tlast 0; end else begin if (send_data tx_udp_payload_axis_tready) begin tx_udp_payload_axis_tvalid 1; tx_udp_payload_axis_tdata data_to_send; if (is_last_data) begin // is_last_data 代表是否是最后一个数据的判断 tx_udp_payload_axis_tlast 1; end end else begin tx_udp_payload_axis_tvalid 0; tx_udp_payload_axis_tlast 0; end end end在这段代码里当满足发送条件somecondition时准备好要发送的数据datatosend并拉高senddata。然后当txudppayloadaxistready为 1 时发送数据并在判断是最后一个数据时拉高txudppayloadaxistlast。总的来说基于 Xilinx K7 325t 实现的这个千兆网 UDP 协议模块虽然功能类似透传但在数据收发的细节处理上还是有不少需要注意的地方希望我的这些分享能给大家带来一些帮助和启发。