万兆以太网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

在这里插入图片描述

四、上板测速

接收带宽可达9.9G
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/550092.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android GridLayoutManager Glide批量加载Bitmap绘制Canvas画在RecyclerView,Kotlin(a)

Android GridLayoutManager Glide批量加载Bitmap绘制Canvas画在RecyclerView&#xff0c;Kotlin&#xff08;a&#xff09; <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name"android.permi…

1 GBDT:梯度提升决策树

1 前言 前面简单梳理的基本的决策树算法&#xff0c;那么如何更好的使用这个基础算法模型去优化我们的结果是本节要探索的主要内容。 梯度提升决策树&#xff08;Gradient Boosting Decision Trees&#xff09;是一种集成学习方法&#xff0c;通常用于解决回归和分类问题。它通…

python之flask安装以及使用

1 flask介绍 Flask是一个非常小的Python Web框架&#xff0c;被称为微型框架&#xff1b;只提供了一个稳健的核心&#xff0c;其他功能全部是通过扩展实现的&#xff1b;意思就是我们可以根据项目的需要量身定制&#xff0c;也意味着我们需要学习各种扩展库的使用。 2 python…

如何在PPT中获得网页般的互动效果

如何在PPT中获得网页般的互动效果 效果可以看视频 PPT中插入网页有互动效果 当然了&#xff0c;获得网页般的互动效果&#xff0c;最简单的方法就是在 PPT 中插入网页呀。 那么如何插入呢&#xff1f; 接下来为你讲解如何获得&#xff08;此方法在 PowerPoint中行得通&#…

吴恩达llama课程笔记:第七课llama安全工具

羊驼Llama是当前最流行的开源大模型&#xff0c;其卓越的性能和广泛的应用领域使其成为业界瞩目的焦点。作为一款由Meta AI发布的开放且高效的大型基础语言模型&#xff0c;Llama拥有7B、13B和70B&#xff08;700亿&#xff09;三种版本&#xff0c;满足不同场景和需求。 吴恩…

ASP.NET MVC中Filter过滤器的使用

MVC Filter是典型的AOP&#xff08;面向切面编程&#xff09;应用&#xff0c;在ASP.NET MVC中的4个过滤器类型&#xff0c;如下&#xff1a; 但是默认实现它们的过滤器只有三种&#xff0c;分别是ActionFilter&#xff08;方法&#xff09;&#xff0c;Authorize&#xff08;授…

微服务之网关路由

一、概述 1.1认识网关 什么是网关&#xff1f; 顾明思议&#xff0c;网关就是网络的关口。数据在网络间传输&#xff0c;从一个网络传输到另一网络时就需要经过网关来做数据的路由和转发以及数据安全的校验。 更通俗的来讲&#xff0c;网关就像是以前园区传达室的大爷。 外…

Pytest精通指南(14)Parametrize之indirect(间接参数)

文章目录 官方概念概念分析官方示例示例分析验证indirect为True但不指定fixture验证indirect为True但不存在fixture 官方概念 概念分析 在pytest的pytest.mark.parametrize装饰器中&#xff0c;indirect参数用于指示是否应该从fixtures中解析参数值&#xff0c;而不是直接使用提…

OpenCV基本图像处理操作(五)——图像数据操作

数据读取 cv2.IMREAD_COLOR&#xff1a;彩色图像cv2.IMREAD_GRAYSCALE&#xff1a;灰度图像 import cv2 #opencv读取的格式是BGR import matplotlib.pyplot as plt import numpy as np %matplotlib inline imgcv2.imread(cat.jpg)数据显示 #图像的显示,也可以创建多个窗口 c…

视频汇聚/安防视频监控云平台EasyCVR云端录像播放与下载的接口调用方法

视频汇聚/安防视频监控云平台EasyCVR支持多协议接入、可分发多格式的视频流&#xff0c;平台支持高清视频的接入、管理、共享&#xff0c;支持7*24小时不间断监控。视频监控管理平台EasyCVR可提供实时远程视频监控、录像、回放与存储、告警、语音对讲、云台控制、平台级联、磁盘…

Flink学习(六)-容错处理

前言 Flink 是通过状态快照实现容错处理 一、State Backends 由 Flink 管理的 keyed state 是一种分片的键/值存储&#xff0c;每个 keyed state 的工作副本都保存在负责该键的 taskmanager 本地中。 一种基于 RocksDB 内嵌 key/value 存储将其工作状态保存在磁盘上&#x…

图像处理与视觉感知---期末复习重点(8)

文章目录 一、图像分类流程二、梯度方向直方图2.1 概述2.2 计算梯度方向直方图2.2.1 过程2.2.2 总结 三、SIFT 一、图像分类流程 流程&#xff1a;输入图像、预处理、特征提取、学习算法、类标。 二、梯度方向直方图 2.1 概述 1. 梯度方向直方图(Histogram of Oriented Gradie…

RabbitMQ交换机的类型

交换机类型 可以看到&#xff0c;在订阅模型中&#xff0c;多了一个exchange角色&#xff0c;而且过程略有变化&#xff1a; Publisher&#xff1a;生产者&#xff0c;不再发送消息到队列中&#xff0c;而是发给交换机 Exchange&#xff1a;交换机&#xff0c;一方面&#xff…

Backend - DRF 序列化(django-rest-framework)

目录 一、restful 、django-rest-framework 、swagger 三者的关系 &#xff08;一&#xff09;restful API&#xff08;REST API&#xff09; 1. rest 2. restful 3. api 4. restfulAPI &#xff08;二&#xff09;django-rest-framework&#xff08;简称DRF&#xff09…

中立分析腾讯云故障相关的事件

最近腾讯云的故障&#xff0c;让一堆云计算爱好者兴奋地远看指点江山、近看沐猴而冠。我比这群爱好者们更了解云计算&#xff0c;但是我尊重我的读者&#xff0c;你们从我这里看到的科普信息&#xff0c;不仅仅只有情绪价值。 在信息爆炸的时代&#xff0c;大家关注和信任某个媒…

如何使用docker-compose安装数据可视化应用JSON Crack并实现远程访问

文章目录 1. 在Linux上使用Docker安装JSONCrack2. 安装Cpolar内网穿透工具3. 配置JSON Crack界面公网地址4. 远程访问 JSONCrack 界面5. 固定 JSONCrack公网地址 JSON Crack 是一款免费的开源数据可视化应用程序&#xff0c;能够将 JSON、YAML、XML、CSV 等数据格式可视化为交互…

微服务中的重要模块

为什么要有微服务&#xff1f; 微服务提高开发效能&#xff0c;避免业务的重复理解&#xff0c;代码重复开发&#xff0c;增加开发效能和代码复用性。 在实际的工作中许多不同的业务有着共同的功能需求&#xff0c;如果我们每遇到一次这种需求就重新去理解构建一次的话会花费大…

msyql中SQL 错误 [1118] [42000]: Row size too large (> 8126)

场景&#xff1a; CREATE TABLE test-qd.eqtree (INSERT INTO test.eqtree (idocid VARCHAR(50) NULL,sfcode VARCHAR(50) NULL,sfname VARCHAR(50) NULL,sfengname VARCHAR(50) NULL,…… ) ENGINEInnoDB DEFAULT CHARSETutf8 COLLATEutf8_general_ci;或 alter table eqtre…

Ctex+texmaker

最近要准备幻灯片&#xff0c;发现我喜欢的模板是用的Ctex&#xff0c;在Texlive下没有办法运行。 于是进行了很多尝试。最后找到一个快捷的办法&#xff0c;删掉自己笔记本中的texlive&#xff0c;在Ctex官网中下载Ctex套件(下载中心 – CTEX)&#xff0c;下载的版本是过时版…

Linux 安装KVM虚拟机

什么是KVM虚拟机&#xff1f; KVM 是 Kernel-based Virtual Machine 的缩写&#xff0c;是一种用于虚拟化的开源硬件虚拟化技术。它使用 Linux 内核的虚拟化模块&#xff0c;将物理服务器划分为多个虚拟机。KVM 允许虚拟机直接访问物理硬件资源,从而提供出色的性能和稳定性,同…