10G_ethernet学习记录(7):UDP层编写

0,UDP层协议

源端口号:自身的端口号;

目的端口号:接受方的端口号;

UDP长度:UDP首部+数据的长度;

UDP校验和:与IP校验和算法一致;

1,工程编写(不包含巨帧数据传输) 

        udp层包含udp_rx,udp_tx,udp_module模块。


module _10g_udp_module
#(
    parameter                           P_SOURCE_PORT = 16'h8080   ,
    parameter                           P_TARGET_PORT = 16'h8080    
)
(
    input                               i_clk                      ,
    input                               i_rst                      ,

    /**************   drp   *********************/
    input              [  15:0]         i_dynamic_source_port      ,
    input                               i_dynamic_source_valid     ,
    input              [  15:0]         i_dynamic_target_port      ,
    input                               i_dynamic_target_valid     ,

    /**************   ip_interface   *********************/
    output             [  63:0]         m_axis_udp2ip_data         ,
    output             [  55:0]         m_axis_udp2ip_user         ,//16len + 8type + 16ip + 3mflag + 13offset
    output             [   7:0]         m_axis_udp2ip_keep         ,
    output                              m_axis_udp2ip_last         ,
    output                              m_axis_udp2ip_valid        ,

    input              [  63:0]         s_axis_ip2udp_data         ,
    input              [  55:0]         s_axis_ip2udp_user         ,//16len + 8type + 16ip + 3mflag + 13offset
    input              [   7:0]         s_axis_ip2udp_keep         ,
    input                               s_axis_ip2udp_last         ,
    input                               s_axis_ip2udp_valid        ,
    /**************   user_interface   *********************/
    input              [  63:0]         s_axis_user_data           ,
    input              [  31:0]         s_axis_user_user           ,//{16'data_len,16'axi_len} //包含两种len,一种时用于传输的len,一种适用于udp头部中的数据长度len
    input              [   7:0]         s_axis_user_keep           ,
    input                               s_axis_user_last           ,
    input                               s_axis_user_valid          ,
    output                              s_axis_user_ready          ,

    output             [  63:0]         m_axis_user_data           ,
    output             [  31:0]         m_axis_user_user           ,//{16'data_len,16'axi_len} //包含两种len,一种时用于传输的len,一种适用于udp头部中的数据长度len
    output             [   7:0]         m_axis_user_keep           ,
    output                              m_axis_user_last           ,
    output                              m_axis_user_valid           
);

        包含于IP层相连接接的接口,以及于用户端相连接的端口。均使用axi接口实现。

        其中在user接口这里, 设定了两种长度,data_len长度,axi_len长度。

  •         data_len:udp传输的数据的具体长度(以1byte划分);
  •         axi_len  : axi接口数据的长度(以8byte划分),用于axi接口模块中的计数;
  [  31:0]         s_axis_user_user           ,//{16'data_len,16'axi_len} //包含两种len,一种时用于传输的len,一种适用于udp头部中的数据长度len

        其转换如下: 其中last_keep为尾端keep,决定最后一个8byte中有多少数据有效。

    assign data_len   = last_keep == 8'b1111_1111 ? axi_len*8:
                        last_keep == 8'b1111_1110 ? (axi_len-1)*8 + 7:
                        last_keep == 8'b1111_1100 ? (axi_len-1)*8 + 6:
                        last_keep == 8'b1111_1000 ? (axi_len-1)*8 + 5:
                        last_keep == 8'b1111_0000 ? (axi_len-1)*8 + 4:
                        last_keep == 8'b1110_0000 ? (axi_len-1)*8 + 3:
                        last_keep == 8'b1100_0000 ? (axi_len-1)*8 + 2:
                        last_keep == 8'b1000_0000 ? (axi_len-1)*8 + 1:
                        axi_len*8 ;

1.1,udp_rx

        接受IP层传递过来的报文 ,提取payload长度,提取payload数据。

        传递给用户端口。

module _10g_udp_rx
#(
    parameter                           P_SOURCE_PORT = 16'h8080   ,
    parameter                           P_TARGET_PORT = 16'h8080    
)
(
    input                               i_clk                      ,
    input                               i_rst                      ,

    /**************   drp   *********************/
    input              [  15:0]         i_dynamic_source_port      ,
    input                               i_dynamic_source_valid     ,
    input              [  15:0]         i_dynamic_target_port      ,
    input                               i_dynamic_target_valid     ,

    /**************   ip_interface   *********************/
    input              [  63:0]         s_axis_ip2udp_data         ,
    input              [  55:0]         s_axis_ip2udp_user         ,//16len + 8type + 16ip + 3mflag + 13offset
    input              [   7:0]         s_axis_ip2udp_keep         ,
    input                               s_axis_ip2udp_last         ,
    input                               s_axis_ip2udp_valid        ,

    /**************   user_interface   *********************/
    output             [  63:0]         m_axis_user_data           ,
    output             [  31:0]         m_axis_user_user           ,//{16'data_len,16'axi_len}
    output             [   7:0]         m_axis_user_keep           ,
    output                              m_axis_user_last           ,
    output                              m_axis_user_valid           
);

仿真波形:

 

 可以看到随着尾部keep的改变,data_len也进行了改变。

user_axi_len相对与ip_axi_len减少了个1,这是因为去除了一个8byte的udp报文头。

多组数据仿真:

测试用例:

    #1000;
    udp_user_data(16'd30 , 8'b1111_1111);
    #100;
    udp_user_data(16'd30 , 8'b1111_0000);

1.2,udp_tx

        将用户传递的数据进行组帧,添加udp报头,发送给IP层。比较简单


module _10g_udp_tx
#(
    parameter                           P_SOURCE_PORT = 16'h8080   ,
    parameter                           P_TARGET_PORT = 16'h8080    
)
(
    input                               i_clk                      ,
    input                               i_rst                      ,

    /**************   drp   *********************/
    input              [  15:0]         i_dynamic_source_port      ,
    input                               i_dynamic_source_valid     ,
    input              [  15:0]         i_dynamic_target_port      ,
    input                               i_dynamic_target_valid     ,

    /**************   ip_interface   *********************/
    output             [  63:0]         m_axis_udp2ip_data         ,
    output             [  55:0]         m_axis_udp2ip_user         ,//16len + 8type + 16ip + 3mflag + 13offset
    output             [   7:0]         m_axis_udp2ip_keep         ,
    output                              m_axis_udp2ip_last         ,
    output                              m_axis_udp2ip_valid        ,

    /**************   user_interface   *********************/
    input              [  63:0]         s_axis_user_data           ,
    input              [  31:0]         s_axis_user_user           ,//{16'data_len,16'axi_len} //包含两种len,一种时用于传输的len,一种适用于udp头部中的数据长度len
    input              [   7:0]         s_axis_user_keep           ,
    input                               s_axis_user_last           ,
    input                               s_axis_user_valid          ,
    output                              s_axis_user_ready           
);

仿真波形:

ip_axi_len 相对user_axi_len与多了个1,这是因为添加了一个8byte的udp报文头。

多组测试也是没有问题的,数据长度正确

测试用例:

    #1000;
    udp_user_data(16'd30 , 8'b1111_1111);
    #100;
    udp_user_data(16'd30 , 8'b1111_0000);
    #100;
    udp_user_data(16'd40 , 8'b1000_0000);
    #100;
    udp_user_data(16'd50 , 8'b1100_0000);

1.3,仿真代码,

进行一个回环测试

`timescale 1ns/1ps

/***************** Information **************************/
// Creat_Time      : 2024/12/17
// Engineer        : 
// Tool_Version    : Vivado_2020.2
// Device          : XCKU060_FFVA1156_2_i
// Function        : tb_udp_module
// Edition         : 
/********************************************************/

module tb_udp_module();

localparam                              P_SOURCE_PORT = 16'h8080   ;
localparam                              P_TARGET_PORT = 16'h8080   ;

reg                                     i_clk                      ;
reg                                     i_rst                      ;

always begin
    i_clk <= 'd0;
    #10;
    i_clk <= 'd1;
    #10;
end

initial begin
    i_rst <= 'd1;
    #100;
    @(posedge i_clk);
    i_rst <= 'd0;
end

logic   [  63:0]         m_axis_udp2ip_data ;
logic   [  55:0]         m_axis_udp2ip_user ;
logic   [   7:0]         m_axis_udp2ip_keep ;
logic                    m_axis_udp2ip_last ;
logic                    m_axis_udp2ip_valid;

logic   [  63:0]         s_axis_ip2udp_data ;
logic   [  55:0]         s_axis_ip2udp_user ;
logic   [   7:0]         s_axis_ip2udp_keep ;
logic                    s_axis_ip2udp_last ;
logic                    s_axis_ip2udp_valid;


logic    [  63:0]         s_axis_user_data  ;
logic    [  31:0]         s_axis_user_user  ;
logic    [   7:0]         s_axis_user_keep  ;
logic                     s_axis_user_last  ;
logic                     s_axis_user_valid ;
logic                     s_axis_user_ready ;

logic    [  63:0]         m_axis_user_data  ;
logic    [  31:0]         m_axis_user_user  ;
logic    [   7:0]         m_axis_user_keep  ;
logic                     m_axis_user_last  ;
logic                     m_axis_user_valid ;

_10g_udp_module
#(
    .P_SOURCE_PORT                     (P_SOURCE_PORT             ),
    .P_TARGET_PORT                     (P_TARGET_PORT             ) 
)
_10g_udp_module_inst
(
    .i_clk                             (i_clk                     ),
    .i_rst                             (i_rst                     ),

    /**************   drp   *********************/
    .i_dynamic_source_port             (                          ),
    .i_dynamic_source_valid            (                          ),
    .i_dynamic_target_port             (                          ),
    .i_dynamic_target_valid            (                          ),

    /**************   ip_interface   *********************/
    .m_axis_udp2ip_data                (m_axis_udp2ip_data        ),
    .m_axis_udp2ip_user                (m_axis_udp2ip_user        ),//16len + 8type + 16ip + 3mflag + 13offset
    .m_axis_udp2ip_keep                (m_axis_udp2ip_keep        ),
    .m_axis_udp2ip_last                (m_axis_udp2ip_last        ),
    .m_axis_udp2ip_valid               (m_axis_udp2ip_valid       ),

    .s_axis_ip2udp_data                (m_axis_udp2ip_data        ),
    .s_axis_ip2udp_user                (m_axis_udp2ip_user        ),//16len + 8type + 16ip + 3mflag + 13offset
    .s_axis_ip2udp_keep                (m_axis_udp2ip_keep        ),
    .s_axis_ip2udp_last                (m_axis_udp2ip_last        ),
    .s_axis_ip2udp_valid               (m_axis_udp2ip_valid       ),
    /**************   user_interface   *********************/
    .s_axis_user_data                  (s_axis_user_data          ),
    .s_axis_user_user                  (s_axis_user_user          ),
    .s_axis_user_keep                  (s_axis_user_keep          ),
    .s_axis_user_last                  (s_axis_user_last          ),
    .s_axis_user_valid                 (s_axis_user_valid         ),
    .s_axis_user_ready                 (s_axis_user_ready         ),

    .m_axis_user_data                  (m_axis_user_data          ),
    .m_axis_user_user                  (m_axis_user_user          ),
    .m_axis_user_keep                  (m_axis_user_keep          ),
    .m_axis_user_last                  (m_axis_user_last          ),
    .m_axis_user_valid                 (m_axis_user_valid         ) 
);

initial begin
    s_axis_user_data   <= 'd0;
    s_axis_user_user   <= 'd0;
    s_axis_user_keep   <= 'd0;
    s_axis_user_last   <= 'd0;
    s_axis_user_valid  <= 'd0;

    #1000;
    udp_user_data(16'd30 , 8'b1111_1111);
    #100;
    udp_user_data(16'd30 , 8'b1111_0000);
    // #100;
    // udp_user_data(16'd40 , 8'b1000_0000);
    // #100;
    // udp_user_data(16'd50 , 8'b1100_0000);
end


task udp_user_data(input [15:0] axi_len , input [7:0] last_keep);
begin:udp_user_data_task
    integer  i;
    logic [15:0] data_len;
    s_axis_user_data   <= 'd0;
    s_axis_user_user   <= 'd0;
    s_axis_user_keep   <= 'd0;
    s_axis_user_last   <= 'd0;
    s_axis_user_valid  <= 'd0;

    assign data_len   = last_keep == 8'b1111_1111 ? axi_len*8:
                        last_keep == 8'b1111_1110 ? (axi_len-1)*8 + 7:
                        last_keep == 8'b1111_1100 ? (axi_len-1)*8 + 6:
                        last_keep == 8'b1111_1000 ? (axi_len-1)*8 + 5:
                        last_keep == 8'b1111_0000 ? (axi_len-1)*8 + 4:
                        last_keep == 8'b1110_0000 ? (axi_len-1)*8 + 3:
                        last_keep == 8'b1100_0000 ? (axi_len-1)*8 + 2:
                        last_keep == 8'b1000_0000 ? (axi_len-1)*8 + 1:
                        axi_len*8 ;
    wait(s_axis_user_ready );
    @(posedge i_clk);
    for(i = 0; i < axi_len ; i = i + 1) begin
        if(i == axi_len - 1) begin
            s_axis_user_data   <= s_axis_user_data + 1;
            s_axis_user_user   <= {data_len ,axi_len};
            s_axis_user_keep   <= last_keep;
            s_axis_user_last   <= 'd1;
            s_axis_user_valid  <= 'd1;
        end
        else begin
            s_axis_user_data   <= s_axis_user_data + 1;
            s_axis_user_user   <= {data_len ,axi_len};
            s_axis_user_keep   <= 8'b1111_1111;
            s_axis_user_last   <= 'd0;
            s_axis_user_valid  <= 'd1;
        end
        @(posedge i_clk);
    end
    s_axis_user_data   <= s_axis_user_data ;
    s_axis_user_user   <= s_axis_user_user ;
    s_axis_user_keep   <= 8'b1111_1111     ;
    s_axis_user_last   <= 'd0;
    s_axis_user_valid  <= 'd0;
end
endtask


endmodule

 

 2,工程编写(包含巨帧数据传输) 

待施工。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值