基于 Xilinx K7 325t 的千兆网 UDP 协议实现小记

基于xilinx k7 325t实现的千兆网udp协议,只需要设置好IP,端口,就可以直接给数据,基本等同于透传,可以不用管底层协议。 可以 # FPGA 实现udp模块说明 ## udp_protocol_top gig_ethernet_pcs_pma有脚本生成,任何版本vivado都可以支持,注释里面有对重要信号的说明,默认是1000M,100M需要改内部信号,PHY芯片是88E1512,SGMII接口。 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_tready=1的时候拉高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芯片是88E1512,SGMII接口。 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_tready=1的时候拉高tx_udp_payload_axis_tvalid,数据才有效,发送完成以后一定要发送一个tx_udp_payload_axis_tlast脉冲指示最后一个数据

下面简单看一下代码结构(这里只是示意,非完整代码):

verilog 复制代码
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

这里面 gigethernet pcspma**模块负责和千兆网物理层相关的处理,而 udp protocol_top 模块则在这个基础上完成 UDP 协议相关的数据收发等功能。

接收数据

在接收数据的时候,当 udpprotocol top.rxudp payloadaxistvalid 拉高,就意味着 udpprotocol top.rxudp payloadaxistdata 里面的数据是有效的。而 udpprotocol top.rxudp payloadaxistready 这个信号默认给 1 的话,就能一直接收数据啦。

从代码逻辑上看,就像下面这样:

verilog 复制代码
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 等)。

发送数据

发送数据也有讲究,当 txudp payloadaxistready = 1 的时候,拉高 txudp payloadaxistvalid,这时的数据才有效。而且在发送完成以后,一定要发送一个 txudp payloadaxistlast 脉冲来指示这是最后一个数据。

看下面这段代码示例:

verilog 复制代码
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**时,准备好要发送的数据 data tosend**并拉高 send data。然后当 txudp payloadaxistready 为 1 时,发送数据,并在判断是最后一个数据时,拉高 txudp payloadaxistlast

总的来说,基于 Xilinx K7 325t 实现的这个千兆网 UDP 协议模块,虽然功能类似透传,但在数据收发的细节处理上还是有不少需要注意的地方,希望我的这些分享能给大家带来一些帮助和启发。

相关推荐
tmlx3I0811 小时前
高光谱拼接算法(六)RANSAC 误匹配剔除
人工智能·算法·机器学习
Mininglamp_27181 小时前
Claude Code 封禁中国开发者之后:本地 AI 编程工具的替代方案实测
开发语言·人工智能·windows·开源软件·ai-native
硅谷秋水1 小时前
World Engine:迈向自动驾驶的后训练时代
人工智能·深度学习·机器学习·计算机视觉·语言模型·自动驾驶
RobinDevNotes1 小时前
PentAGI:全自主 AI 渗透测试代理系统
人工智能
明理的信封1 小时前
AI 基础设施的“去 Python 化“:Rust 与 C# 的两条替代路径
人工智能·python·rust
优橙教育1 小时前
Rano AI智能体技术架构深度解析
人工智能
Tiansan66661 小时前
郑州AI问答推广公司:如何用AI提升转化率
人工智能·郑州ai问答推广公司
龙亘川1 小时前
开源本地 AI 智能体网关 OpenClaw 深度实践:架构解析、全场景部署与自动化落地指南
人工智能·架构·开源·openclaw
霍格沃兹测试开发学社测试人社区2 小时前
为企业提供专业、灵活、高效的一体化测试支持
人工智能
xixixi777772 小时前
产业全景解读:太空算力、国产芯、国产大模型、6G 空天地、AI 可信身份、后量子安全多线全面突破
人工智能·安全·ai·大模型·数据中心·通信·运营商