万兆以太网MAC设计(5)MAC_TX模块设计以及上板带宽测试

这篇具有很好参考价值的文章主要介绍了万兆以太网MAC设计(5)MAC_TX模块设计以及上板带宽测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

MAC_RX的设计暂时告一段落,本节将开始进行MAC_TX的设计。

一、模块功能

  1. 接收上层用户的AXIS数据,将其转换为XGMII进接口的数据发送给IP核。
  2. 可接受AXIS数据流,可支持数据包之间的间隔最小为一个时钟周期
  3. 目的MAC以及源MAC等参数可动态配置
  4. 流控,万兆以太网帧间隔为9.6ns,用户时钟频率为156.25Mhz,周期为6.4ns,因此XGMII接口数据之前至少间隔2个时钟周期

模块接口如下:

module TEN_GIG_MAC_TX#(
    parameter       P_SRC_MAC = 48'h00_00_00_00_00_00,
    parameter       P_DST_MAC = 48'h00_00_00_00_00_00
)(
    input           i_clk               ,
    input           i_rst               ,

    input  [47:0]   i_dynamic_src_mac   ,
    input           i_dynamic_src_valid ,
    input  [47:0]   i_dynamic_dst_mac   ,
    input           i_dynamic_dst_valid ,

    input  [63:0]   s_axis_tdata        ,
    input  [79:0]   s_axis_tuser        ,
    input  [7 :0]   s_axis_tkeep        ,
    input           s_axis_tlast        ,
    input           s_axis_tvalid       ,
    output          s_axis_tready       ,

    output [63:0]   o_xgmii_txd         ,
    output [7 :0]   o_xgmii_txc         
);

二、实现方式

  1. 将接收到的AXIS数据先存入FIFO,将包头组织完毕后从FIFO当中读取数据进行填充
  2. 组帧同时要进行CRC计算并且在末尾填充,需要注意,在尾端填充CRC数据时,根据尾端keep信号有多种情况,会存在数据额外需要一个时钟周期进行传输CRC数据。

包含子模块如下:

FIFO_64X256 FIFO_64X256_data_tx (
  .clk          (i_clk              ),
  .srst         (i_rst              ),  
  .din          (rs_axis_tdata      ),
  .wr_en        (rs_axis_tvalid     ),
  .rd_en        (r_fifo_data_rden   ),
  .dout         (w_fifo_data_dout   ),
  .full         (w_fifo_data_full   ),
  .empty        (w_fifo_data_empty  ) 
);

FIFO_32X32 FIFO_32X32_len_type (
  .clk          (i_clk                  ), 
  .srst         (i_rst              ),      
  .din          ({rs_axis_tuser[79:64],rs_axis_tuser[15:0]}),     
  .wr_en        (rs_axis_tlast          ),  
  .rd_en        (r_fifo_len_type_rden   ),  
  .dout         (w_fifo_len_type_dout   ),  
  .full         (w_fifo_len_type_full   ),  
  .empty        (w_fifo_len_type_empty  )  
);

FIFO_8X32 FIFO_8X32_tail_keep (
  .clk          (i_clk              ),  
  .srst         (i_rst              ),    
  .din          (rs_axis_tkeep      ),  
  .wr_en        (rs_axis_tlast      ),  
  .rd_en        (r_fifo_keep_rden   ),  
  .dout         (w_fifo_keep_dout   ),  
  .full         (w_fifo_keep_full   ),  
  .empty        (w_fifo_keep_empty  ) 
);

CRC32_64bKEEP CRC32_64bKEEP_u0(
  .i_clk        (i_clk              ),
  .i_rst        (i_rst              ),
  .i_en         (r_crc_en           ),
  .i_data       (r_crc_data[63:56]  ),
  .i_data_1     (r_crc_data[55:48]  ),
  .i_data_2     (r_crc_data[47:40]  ),
  .i_data_3     (r_crc_data[39:32]  ),
  .i_data_4     (r_crc_data[31:24]  ),
  .i_data_5     (r_crc_data[23:16]  ),
  .i_data_6     (r_crc_data[15: 8]  ),
  .i_data_7     (r_crc_data[7 : 0]  ),
  .o_crc_8      (w_crc_8_big        ),
  .o_crc_1      (w_crc_1_big        ),
  .o_crc_2      (w_crc_2_big        ),
  .o_crc_3      (w_crc_3_big        ),
  .o_crc_4      (w_crc_4_big        ),
  .o_crc_5      (w_crc_5_big        ),
  .o_crc_6      (w_crc_6_big        ),
  .o_crc_7      (w_crc_7_big        ) 
);

产生XGMII接口的核心代码如下:

//r_xgmii_txc还需要考虑最后多加4byte的CRC
always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_xgmii_txc <= 8'b1111_1111;
    else if(r_fifo_len_type_rden)
        r_xgmii_txc <= 8'b1000_0000;
    else if(r_pkt_cnt == r_data_len + 3 && r_tail_keep >= 8'b1111_1000)
        case (r_tail_keep)
            8'b1111_1111    : r_xgmii_txc <= 8'b0001_1111;
            8'b1111_1110    : r_xgmii_txc <= 8'b0011_1111;
            8'b1111_1100    : r_xgmii_txc <= 8'b0111_1111;
            8'b1111_1000    : r_xgmii_txc <= 8'b1111_1111;
            default         : r_xgmii_txc <= 8'b0000_0000;
        endcase
    else if(r_pkt_cnt == r_data_len + 2 && r_tail_keep < 8'b1111_1000)
        case (r_tail_keep)      
            8'b1111_0000    : r_xgmii_txc <= 8'b0000_0001;
            8'b1110_0000    : r_xgmii_txc <= 8'b0000_0011;
            8'b1100_0000    : r_xgmii_txc <= 8'b0000_0111;
            8'b1000_0000    : r_xgmii_txc <= 8'b0000_1111;
            default         : r_xgmii_txc <= 8'b0000_0000;
        endcase
    else if(r_send_data)
        r_xgmii_txc <= 8'b0000_0000;
    else
        r_xgmii_txc <= 8'b1111_1111;
end

always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_send_data <= 'd0;
    else if(r_pkt_cnt == r_data_len + 3 && r_tail_keep >= 8'b1111_1000)
        r_send_data <= 'd0;
    else if(r_pkt_cnt == r_data_len + 2 && r_tail_keep < 8'b1111_1000)
        r_send_data <= 'd0;
    else if(r_fifo_len_type_rden)
        r_send_data <= 'd1;
    else
        r_send_data <= r_send_data;
end

always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        ro_xgmii_txd <= {8{P_FRAME_IDLE}};
    else if(r_pkt_cnt_3d == r_data_len + 2)
        case (r_tail_keep_1d)
            8'b1111_1111    : ro_xgmii_txd <= {r_xgmii_txd_2d[63: 8],r_crc_result[31:24]};
            8'b1111_1110    : ro_xgmii_txd <= {r_xgmii_txd_2d[63:16],r_crc_result[31:16]};
            8'b1111_1100    : ro_xgmii_txd <= {r_xgmii_txd_2d[63:24],r_crc_result[31: 8]};
            8'b1111_1000    : ro_xgmii_txd <= {r_xgmii_txd_2d[63:32],r_crc_result[31: 0]};
            8'b1111_0000    : ro_xgmii_txd <= {r_xgmii_txd_2d[63:40],r_crc_result[31: 0],P_FRAME_END};
            8'b1110_0000    : ro_xgmii_txd <= {r_xgmii_txd_2d[63:48],r_crc_result[31: 0],P_FRAME_END,P_FRAME_IDLE};
            8'b1100_0000    : ro_xgmii_txd <= {r_xgmii_txd_2d[63:56],r_crc_result[31: 0],P_FRAME_END,P_FRAME_IDLE,P_FRAME_IDLE};
            8'b1000_0000    : ro_xgmii_txd <= {r_crc_result[31: 0],P_FRAME_END,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE};
            default         : ro_xgmii_txd <= {8{P_FRAME_IDLE}};
        endcase 
    else if(r_pkt_cnt_3d == r_data_len + 3 && r_tail_keep >= 8'b1111_1000)
        case (r_tail_keep_1d)      
            8'b1111_1111    : ro_xgmii_txd <= {r_crc_result[23:0],P_FRAME_END,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE};  
            8'b1111_1110    : ro_xgmii_txd <= {r_crc_result[15:0],P_FRAME_END,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE};  
            8'b1111_1100    : ro_xgmii_txd <= {r_crc_result[7 :0],P_FRAME_END,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE};  
            8'b1111_1000    : ro_xgmii_txd <= {P_FRAME_END,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE,P_FRAME_IDLE};
            default         : ro_xgmii_txd <= {8{P_FRAME_IDLE}};
        endcase      
    else
        ro_xgmii_txd <= r_xgmii_txd_2d;
end

三、仿真

模块AXIS_test_module会产生各种不同尾端keep的数据包,用于测试发送端的各种情况,包长为1488byte,间隔为6个时钟周期(AXIS用户端包间隔为6,则XGMII处数据间隔为2,俩者之间相差4),通过查看主机侧网卡接收带宽检查FPGA侧发送是否符合要求。

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        rm_axis_tkeep <= 8'hff;
    else if(r_send_cnt == P_SEND_LEN - 1 && w_axis_active)
        rm_axis_tkeep <= 8'hff;
    else if(r_send_cnt == P_SEND_LEN - 2 && w_axis_active)
        case (r_pkt_cnt)
            0   : rm_axis_tkeep <= 8'b1111_1111;
            1   : rm_axis_tkeep <= 8'b1111_1110;
            2   : rm_axis_tkeep <= 8'b1111_1100;
            3   : rm_axis_tkeep <= 8'b1111_1000;
            4   : rm_axis_tkeep <= 8'b1111_0000;
            5   : rm_axis_tkeep <= 8'b1110_0000;
            6   : rm_axis_tkeep <= 8'b1100_0000;
            7   : rm_axis_tkeep <= 8'b1000_0000;
            default: rm_axis_tkeep <= 8'b1111_1111;
        endcase
        
    else
        rm_axis_tkeep <= 8'hff;
end

万兆以太网MAC设计(5)MAC_TX模块设计以及上板带宽测试,万兆以太网设计,fpga开发,网络协议

四、上板测速

接收带宽可达9.9G
万兆以太网MAC设计(5)MAC_TX模块设计以及上板带宽测试,万兆以太网设计,fpga开发,网络协议文章来源地址https://www.toymoban.com/news/detail-854166.html

到了这里,关于万兆以太网MAC设计(5)MAC_TX模块设计以及上板带宽测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • wireshark以太网 MAC 帧分析

    注 1 : 正文区的目录结构。一级标题用阿拉伯数字大写,二级以下 ( 含 ) 用点分式阿拉伯数字。 注 2 :实验介绍及回答部分,均可图文并用;如用图,建议居中显示,并附上图标题 ( 编好图号 ) 一、 实验 目的 1.理解以太网 MAC 地址 2.学习并分析以太网 MAC 帧格式的结构、含

    2024年02月04日
    浏览(53)
  • 【MAC+IP】以太网帧格式

    图片出自:https://info.support.huawei.com/info-finder/encyclopedia/zh/MTU.html

    2024年02月05日
    浏览(47)
  • 以太网MAC与PHY(二)

    目录 一、概述 二、MAC控制器 三、PHY 四、SMI协议         以太网硬件主要包括OSI的最下面两层,物理层和数据链路层 物理层:定义了数据传送与接收所需要的电与光信号、线路状态、时钟基准、数据编码和电路等,并向数据链路层提供标准接口。物理层的芯片为PHY 数据

    2024年02月09日
    浏览(52)
  • 以太网基础理论—MAC+PHY

    MAC (Medium Access Control),简称媒体访问控制。MAC层在OSI模型中是属于数据链路层,其主要任务是解决数据包发给谁。数据链路层包含MAC(介质访问控制)子层和LLC(逻辑链路控制)子层。   PHY(physical),简称物理层,是一个对OSI模型物理层的简称。PHY包括两个接口三个子层

    2024年02月14日
    浏览(45)
  • 以太网(一)MAC、MII、PHY 介绍

    以太网(二)PHY、网卡、SWITCH介绍 [link] 以太网是由CPU,MAC,PHY三部分组成的,如下图示意: 但是,在实际的设计中,CPU、MAC和PHY三部分并不一定是独立分开的,存在以下三种方式: MAC 与 PHY集成在CPU中,目前来说并不多见。 MAC集成在CPU中,而PHY 采用独立芯片,这种比较常

    2024年01月18日
    浏览(55)
  • WOL唤醒配置(以太网、PHY、MAC)

    目录 wol  以太网 MAC PHY RMII 通信配置 总结 Wake-on-LAN简称WOL,WOL(网络唤醒) 是一种标准网络协议,它的功效在于让已经进入休眠状态或关机状态的计算机,透过局域网(多半为以太网)的另一端对其发令,使其从休眠状态唤醒、恢复成运作状态,或从关机状态转成引导状态

    2024年02月03日
    浏览(70)
  • 华为数通 以太网交换机——常见MAC操作

    目录 Ⅰ  查看所有MAC地址 Ⅱ  查看某个接口学习到的MAC地址 Ⅲ  查看某个VLAN学习到的MAC地址 Ⅳ  查看系统的MAC地址 Ⅴ  查看接口的MAC地址 Ⅵ  查看VLANIF接口的MAC地址 Ⅶ  根据IP获取对应设备的MAC地址 Ⅷ  配置静态MAC地址 Ⅸ  配置黑洞MAC地址 Ⅹ  查看和配置MAC地址的老化

    2024年04月16日
    浏览(51)
  • 基于 AN108 模块的ADC 采集以太网传输

    本文基于AN108模块,将ADC采集的数据通过以太网传输到上位机。 本实验的硬件设计部分及vitis均参照了ALINX FPGA ZYNQ Ultrascale+ MPSOC教程中实验 基于 AN9280模块的 ADC 采集以太网传输,其B站视频链接如下 【62】ALINX Zynq MPSoC XILINX FPGA视频教程 SDK 裸机开发—ADC以太网传输协议_哔哩哔

    2023年04月08日
    浏览(53)
  • 4.2.2 以太网技术(二) MAC地址和MAC帧的格式

    4.2.2 以太网技术(二) MAC地址和MAC帧的格式 前面我们提出了两个问题中第一个是在总线式的广播信道中我们如何实现计算机之间一对一的通信?为了在总线上实现一对一的通信我们可以使每一台计算机都拥有一个和其他的计算机不同的地址,也就是说每一台计算机的地址是

    2024年02月05日
    浏览(55)
  • 以太网基础知识——PHY,MAC,MII,switch

    在以太网开发中,常常会听到一些专业名词,例如PHY,MAC,MII,switch,下面是解释 PHY PHY 是物理接口收发器,它实现物理层。包括 MII/GMII (介质独立接口) 子层、PCS (物理编码子层) 、PMA (物理介质附加) 子层、PMD (物理介质相关) 子层、MDI 子层。定义了数据传送与接收所需要的

    2024年02月04日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包