万兆以太网MAC设计(2)MAC_RX模块
文章目录
- 前言
- 一、模块功能
- 二、代码
- 三、仿真波形
前言
上文我们打通了了万兆以太网物理层和数据链路层,其实就是会使用IP核了,本文将正式开始MAC层设计第一篇,接收端设计。
一、模块功能
MAC_RX模块功能如下:
- 解析接收的报文:接受报文的目的MAC、源MAC、报文类型
- 将XGMII接口输入数据转化为AXIS的数据流形式传递给上层用户
难点在于数据格式的转化,最主要的是尾端KEEP信号该如何与有效数据进行对齐。
数据恢复的过程:
- 判断起始位SOF和起始位的位置:起始字节8‘hFB’位置存在俩种情况:第一种情况自然是在接收数据的第一个字节位置,但也存在在第五个字节位置的情况,所以需要分情况讨论。

- 关键字段信息提取:根据起始位置的不同,目的MAC以及源MAC和类型信息都要分情况进行讨论。
- 数据恢复:同理,恢复数据也需要讨论。
- 结束位EOF以及结束位的位置判断 :结束位有八种情况,一拍数据64bit,结束位可能存在在任何一个byte上。
- 尾端KEPP对齐,根据起始位位置以及结束位位置,尾端KEEP信号需要讨论各种情况。
- AXIS数据转换 :前面相当于把KEEP和DATA信号处理好了,然后还需要产生VALID、LAST、USER信号。
二、代码
设计思路参考了FPGA奇哥系列网课
注意一下几点:
- 老生常谈的大小端问题,进入该模块的数据全部应该是大端数据,我完全是按照大端进行处理的。
- LAST信号和KEEP信号分类讨论条件是一样的,俩者是在数据尾端同时进行变化的,根据最后一拍有效数据字节数的多少,LAST信号会在不同的时刻拉高(在r_eof拉高或w_eof拉高时刻)。
- USER信号是用户自定义的,我这里暂时定义为接收数据的源MAC的低16位加类型(16位)。
- 万兆以太网控制字符定义:

module TEN_GIG_MAC_RX(input i_clk ,input i_rst ,input [63:0] i_xgmii_rxd ,input [7 :0] i_xgmii_rxc ,output [63:0] m_axis_rdata ,output [31:0] m_axis_ruser ,//用户自定义{r_src_mac[15:0],r_type}output [7 :0] m_axis_rkeep ,output m_axis_rlast ,output m_axis_rvalid
);
/******************************function*****************************//******************************parameter****************************/
localparam P_FRAME_IDLE = 8'h07 ,P_FRAME_START = 8'hFB ,P_FRAME_END = 8'hFD ,P_FRAME_EEROR = 8'hFE ;
/******************************mechine******************************//******************************reg**********************************/
reg [63:0] ri_xgmii_rxd ;
reg [63:0] ri_xgmii_rxd_1d ;
reg [7 :0] ri_xgmii_rxc ;
reg [7 :0] ri_xgmii_rxc_1d ;
reg [63:0] rm_axis_rdata ;
//reg [63:0] rm_axis_rdata_1d ;
reg [31:0] rm_axis_ruser ;
reg [7 :0] rm_axis_rkeep ;
reg rm_axis_rlast ;
reg rm_axis_rvalid ;
//解析接收数据
reg [15:0] r_recv_cnt ;
reg r_comma ;
reg [47:0] r_dst_mac ;
reg [47:0] r_src_mac ;
reg [15:0] r_type ;
reg r_data_run ;//开始产生axis输出数据
reg r_data_run_1d ;
reg r_data_run_2d ;reg r_sof ;
reg r_eof ;
reg [2 :0] r_sof_location ;
reg [2 :0] r_eof_location ;
/******************************wire*********************************/
wire w_sof ;
wire w_eof ;
wire [2 :0] w_sof_location ;
wire [2 :0] w_eof_location ;
/******************************component****************************//******************************assign*******************************/
assign m_axis_rdata = rm_axis_rdata ;
assign m_axis_ruser = rm_axis_ruser ;
assign m_axis_rkeep = rm_axis_rkeep ;
assign m_axis_rlast = rm_axis_rlast ;
assign m_axis_rvalid = rm_axis_rvalid ;
//进入该模块的数据已经全部被转换为大端模式
//开始字符以及位置判断
assign w_sof = ((ri_xgmii_rxd[63:56] == P_FRAME_START) && (ri_xgmii_rxc[7] == 1)) || ((ri_xgmii_rxd[31:24] == P_FRAME_START) && (ri_xgmii_rxc[3] == 1));
assign w_sof_location = ((ri_xgmii_rxd[63:56] == P_FRAME_START) && (ri_xgmii_rxc[7] == 1)) ? 7 : ((ri_xgmii_rxd[31:24] == P_FRAME_START) && (ri_xgmii_rxc[3] == 1)) ? 3 :0;
//结束字符以及位置判断
assign w_eof = ((ri_xgmii_rxd[63:56] == P_FRAME_END) && (ri_xgmii_rxc[7] == 1)) || ((ri_xgmii_rxd[55:48] == P_FRAME_END) && (ri_xgmii_rxc[6] == 1)) ||((ri_xgmii_rxd[47:40] == P_FRAME_END) && (ri_xgmii_rxc[5] == 1)) ||((ri_xgmii_rxd[39:32] == P_FRAME_END) && (ri_xgmii_rxc[4] == 1)) ||((ri_xgmii_rxd[31:24] == P_FRAME_END) && (ri_xgmii_rxc[3] == 1)) ||((ri_xgmii_rxd[23:16] == P_FRAME_END) && (ri_xgmii_rxc[2] == 1)) ||((ri_xgmii_rxd[15: 8] == P_FRAME_END) && (ri_xgmii_rxc[1] == 1)) ||((ri_xgmii_rxd[7 : 0] == P_FRAME_END) && (ri_xgmii_rxc[0] == 1));assign w_eof_location = ((ri_xgmii_rxd[63:56] == P_FRAME_END) && (ri_xgmii_rxc[7] == 1)) ? 7 : ((ri_xgmii_rxd[55:48] == P_FRAME_END) && (ri_xgmii_rxc[6] == 1)) ? 6 :((ri_xgmii_rxd[47:40] == P_FRAME_END) && (ri_xgmii_rxc[5] == 1)) ? 5 :((ri_xgmii_rxd[39:32] == P_FRAME_END) && (ri_xgmii_rxc[4] == 1)) ? 4 :((ri_xgmii_rxd[31:24] == P_FRAME_END) && (ri_xgmii_rxc[3] == 1)) ? 3 :((ri_xgmii_rxd[23:16] == P_FRAME_END) && (ri_xgmii_rxc[2] == 1)) ? 2 :((ri_xgmii_rxd[15: 8] == P_FRAME_END) && (ri_xgmii_rxc[1] == 1)) ? 1 :((ri_xgmii_rxd[7 : 0] == P_FRAME_END) && (ri_xgmii_rxc[0] == 1)) ? 0 : 0;
/******************************always*******************************/
always @(posedge i_clk or posedge i_rst)beginif(i_rst)beginri_xgmii_rxd <= 'd0;ri_xgmii_rxc <= 'd0;ri_xgmii_rxd_1d <= 'd0;ri_xgmii_rxc_1d <= 'd0;endelse beginri_xgmii_rxd <= i_xgmii_rxd ;ri_xgmii_rxc <= i_xgmii_rxc ;ri_xgmii_rxd_1d <= ri_xgmii_rxd ;ri_xgmii_rxc_1d <= ri_xgmii_rxc ;end
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)beginr_sof <= 'd0;r_sof_location <= 'd0;endelse if(w_sof)beginr_sof <= w_sof ;r_sof_location <= w_sof_location ;endelse beginr_sof <= 'd0 ;r_sof_location <= r_sof_location ;end
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)beginr_eof <= 'd0;r_eof_location <= 'd0;endelse if(w_eof)beginr_eof <= w_eof ;r_eof_location <= w_eof_location ;endelse beginr_eof <= 'd0 ;r_eof_location <= r_eof_location ; end
end always @(posedge i_clk or posedge i_rst)beginif(i_rst)r_comma <= 'd0;else if(r_eof)r_comma <= 'd0;else if((r_sof_location == 7) && (ri_xgmii_rxd_1d[55:0] == 56'h55_5555_5555_5555) && (ri_xgmii_rxd[63:56] == 8'hd5))r_comma <= 'd1;else if((r_sof_location == 3) && (ri_xgmii_rxd_1d[23:0] == 24'h55_5555) && (ri_xgmii_rxd[63:24] == 40'h55_5555_55d5))r_comma <= 'd1;elser_comma <= r_comma;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)r_recv_cnt <= 'd0;else if(r_eof)r_recv_cnt <= 'd0;else if(r_sof | r_recv_cnt)r_recv_cnt <= r_recv_cnt + 'd1;elser_recv_cnt <= r_recv_cnt;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)r_dst_mac <= 'd0;else if(r_sof_location == 7 && r_recv_cnt == 1)r_dst_mac <= ri_xgmii_rxd_1d[55:8];else if(r_sof_location == 3 && r_recv_cnt == 1)r_dst_mac <= {ri_xgmii_rxd_1d[23:0],ri_xgmii_rxd[63:40]};elser_dst_mac <= r_dst_mac;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)r_src_mac <= 'd0;else if(r_sof_location == 7 && r_recv_cnt == 1)r_src_mac <= {ri_xgmii_rxd_1d[7:0],ri_xgmii_rxd[63:24]};else if(r_sof_location == 3 && r_recv_cnt == 2)r_src_mac <= {ri_xgmii_rxd_1d[39:0],ri_xgmii_rxd[63:56]};elser_src_mac <= r_src_mac;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)r_type <= 'd0;else if(r_sof_location == 7 && r_recv_cnt == 2)r_type <= ri_xgmii_rxd_1d[23:8];else if(r_sof_location == 3 && r_recv_cnt == 3)r_type <= ri_xgmii_rxd_1d[55:40];elser_type <= r_type;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)r_data_run <= 'd0;else if(rm_axis_rlast)r_data_run <= 'd0;else if(r_sof_location == 7 && r_recv_cnt == 1)r_data_run <= 'd1;else if(r_sof_location == 3 && r_recv_cnt == 2)r_data_run <= 'd1;elser_data_run <= r_data_run;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)beginr_data_run_1d <= 'd0;r_data_run_2d <= 'd0;endelse beginr_data_run_1d <= r_data_run;r_data_run_2d <= r_data_run_1d;end
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)rm_axis_rdata <= 'd0;else if(rm_axis_rlast)rm_axis_rdata <= 'd0;else if(r_sof_location == 7 && r_data_run)rm_axis_rdata <= {ri_xgmii_rxd_1d[7:0],ri_xgmii_rxd[63:8]};else if(r_sof_location == 3 && r_data_run)rm_axis_rdata <= {ri_xgmii_rxd_1d[39:0],ri_xgmii_rxd[63:40]};elserm_axis_rdata <= 'd0;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)rm_axis_ruser <= 'd0;else if(r_sof_location == 7 && r_recv_cnt == 2)rm_axis_ruser <= {r_src_mac,ri_xgmii_rxd_1d[23:8]};else if(r_sof_location == 3 && r_recv_cnt == 3)rm_axis_ruser <= {r_src_mac,ri_xgmii_rxd_1d[55:40]};elserm_axis_ruser <= rm_axis_ruser;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)rm_axis_rkeep <= 'd0;else if(r_sof_location == 7 && w_eof)case (w_eof_location)7 : rm_axis_rkeep <= 8'b1000_0000;6 : rm_axis_rkeep <= 8'b1100_0000;5 : rm_axis_rkeep <= 8'b1110_0000;4 : rm_axis_rkeep <= 8'b1111_0000;3 : rm_axis_rkeep <= 8'b1111_1000;2 : rm_axis_rkeep <= 8'b1111_1100;1 : rm_axis_rkeep <= 8'b1111_1110;0 : rm_axis_rkeep <= 8'b1111_1111;default : rm_axis_rkeep <= 8'b1111_1111;endcaseelse if(r_sof_location == 3 && (w_eof && w_eof_location >= 4))case (w_eof_location)7 : rm_axis_rkeep <= 8'b1111_1000;6 : rm_axis_rkeep <= 8'b1111_1100;5 : rm_axis_rkeep <= 8'b1111_1110;4 : rm_axis_rkeep <= 8'b1111_1111;3 : rm_axis_rkeep <= 8'b1000_0000;2 : rm_axis_rkeep <= 8'b1100_0000;1 : rm_axis_rkeep <= 8'b1110_0000;0 : rm_axis_rkeep <= 8'b1111_0000;default : rm_axis_rkeep <= 8'b1111_1111;endcaseelse if(r_sof_location == 3 && (r_eof && r_eof_location < 4))case (r_eof_location)7 : rm_axis_rkeep <= 8'b1111_1000;6 : rm_axis_rkeep <= 8'b1111_1100;5 : rm_axis_rkeep <= 8'b1111_1110;4 : rm_axis_rkeep <= 8'b1111_1111;3 : rm_axis_rkeep <= 8'b1000_0000;2 : rm_axis_rkeep <= 8'b1100_0000;1 : rm_axis_rkeep <= 8'b1110_0000;0 : rm_axis_rkeep <= 8'b1111_0000;default : rm_axis_rkeep <= 8'b1111_1111;endcaseelserm_axis_rkeep <= 8'b1111_1111;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)rm_axis_rlast <= 'd0;else if(r_sof_location == 7 && w_eof)rm_axis_rlast <= 'd1;else if(r_sof_location == 3 && (w_eof && w_eof_location >= 4))rm_axis_rlast <= 'd1;else if(r_sof_location == 3 && (r_eof && r_eof_location < 4))rm_axis_rlast <= 'd1;elserm_axis_rlast <= 'd0;
endalways @(posedge i_clk or posedge i_rst)beginif(i_rst)rm_axis_rvalid <= 'd0;else if(rm_axis_rlast)rm_axis_rvalid <= 'd0;else if(r_data_run && !r_data_run_1d)rm_axis_rvalid <= 'd1;elserm_axis_rvalid <= rm_axis_rvalid;
endendmodule
三、仿真波形
仿真文件当中要遍历所有的起始位置与结束为止组合,一共16种。

以起始位在第五个byte,结束位在第一个byte为例,其波形如下,结果正确,对比其他16种情况,波形全部正确。

相关文章:
万兆以太网MAC设计(2)MAC_RX模块
文章目录 前言一、模块功能二、代码三、仿真波形 前言 上文我们打通了了万兆以太网物理层和数据链路层,其实就是会使用IP核了,本文将正式开始MAC层设计第一篇,接收端设计。 一、模块功能 MAC_RX模块功能如下: 解析接收的报文&…...
D. Solve The Maze Codeforces Round 648 (Div. 2)
题目链接: Problem - 1365D - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/problemset/problem/1365/D 题目大意: 有一张地图n行m列(地图外面全是墙),…...
CPU核心数、线程数都是什么意思?
最早,每个物理 cpu 上只有一个核心,对操作系统而言,也就是同一时刻只能运行一个进程/线程。 为了提高性能,cpu 厂商开始在单个物理 cpu 上增加核心(实实在在的硬件存在),也就出现了多核 cpu&…...
每日一篇 4.12
misstep:失误 epic proportions.:史无前例 arguably:按理来说 assembly:组装 performed :执行 underpins:支撑 holds a monopoly:垄断了 shipped:发货 a market capitalizati…...
鸿蒙南向开发:【智能烟感】
样例简介 智能烟感系统通过实时监测环境中烟雾浓度,当烟雾浓度超标时,及时向用户发出警报。在连接网络后,配合数字管家应用,用户可以远程配置智能烟感系统的报警阈值,远程接收智能烟感系统报警信息。实现对危险及时报…...
【主题广|检索稳定】2024年生态工程与农业科技国际会议 (EEAT 2024)
2024年生态工程与农业科技国际会议 (EEAT 2024) 2024 International Conference on Ecological Engineering and Agricultural Technology 【会议简介】 2024年生态工程与农业科技国际会议即将在贵阳召开。本次会议将汇集全球生态工程与农业科技领域的专家学者,共…...
代码随想录算法训练营第三十八天|509. 斐波那契数、 70. 爬楼梯、746. 使用最小花费爬楼梯
509 题目: 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) 0,F(1) 1 F(n) F(n - 1) F(n - 2),…...
07-app端文章搜索
app端文章搜索 1) 今日内容介绍 1.1)App端搜索-效果图 1.2)今日内容 文章搜索 ElasticSearch环境搭建 索引库创建 文章搜索多条件复合查询 索引数据同步 搜索历史记录 Mongodb环境搭建 异步保存搜索历史 查看搜索历史列表 删除搜索历史 联想词查询 联想词的来源 联…...
✔ ★Java项目——设计一个消息队列(二)
Java项目——设计一个消息队列 四. 项⽬创建五. 创建核⼼类创建 Exchange(名字、类型、持久化)创建 MSGQueue(名字、持久化、独占标识)创建 Binding(交换机名字、队列名字、bindingKey用于与routingKey匹配)…...
Java语言实现生产者/消费者问题
经典例题:生产者/消费者问题 生产者(Productor)将产品放在柜台(Counter),而消费者(Customer)从柜台 处取走产品,生产者一次只能生产固定数量的产品(比如:1), 这时柜台中不能 再放产品,此时生产者应停止生产等待消费者…...
bugku-web-file_get_contents
<?php extract($_GET); if (!empty($ac)){$f trim(file_get_contents($fn));if ($ac $f){echo "<p>This is flag:" ." $flag</p>";}else{echo "<p>sorry!</p>";} } ?> 这里涉及到几个不常用的函数 这里直接构…...
Python数据处理和常用库(如NumPy、Pandas)
Python是一种功能强大的编程语言,广泛应用于数据处理和分析领域。在Python中,有一些常用的库可以帮助我们进行数据处理和分析,其中包括NumPy和Pandas。下面是关于这两个库的简介和使用示例:NumPy(Numerical Python&…...
[SystemVerilog]Simulation and Test Benches
Simulation and Test Benches 测试语言中有很大一部分专门用于测试台和测试。在本章中,我们将介绍为硬件设计编写高效测试台的一些常用技术。 6.1 How SystemVerilog Simulator Works 在深入研究如何编写适当的测试台之前,我们需要深入了解模拟器的工作原…...
lightgbm-安装失败(解决方案)
1.pip install lightgbm 报错,出现长篇标黄和标红的,本人表示看不懂,直接忽略,如下所示: 2.尝试pip install lightgbm -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com,安装也报错&…...
halcon图像相减算子sub_image
1.图像相减算子 sub_image(ImageMinuend , ImageSubtrahend : ImageSub : Mult , Add :) (1)参数解释: ImageMinuend :输入参数需要被减的图片 ImageSubtrahend :输入参数拿来减的图片 ImageSub :输出…...
final、finally 和 finalize 有什么区别?
final 是一个关键字,用于声明一个类、方法或变量。当用 final 修饰一个类时,表示该类不能被继承;当用 final 修饰一个方法时,表示该方法不能被子类重写;当用 final 修饰一个变量时,表示该变量只能被赋值一次…...
智能运维场景 | 科技风险预警,能实现到什么程度?
[ 原作者:擎创夏洛克,本文略做了节选和改编 ] 每次一说到“风险预警”,就会有客户问我们能做怎样的风险预警。实际上在智能运维厂商来说,此风险非彼风险,不是能做银行的业务上的风险预警(比如贷款风险等&a…...
中颖51芯片学习3. 定时器
中颖51芯片学习3. 定时器 一、SH79F9476定时器简介1. 简介2. 定时器运行模式 二、定时器21. 说明(1)时钟(2)工作模式 2. 寄存器(1)控制寄存器 T2CON(2)定时器2模式控制寄存器 T2MOD …...
[python] Numpy库用法(持续更新)
先导入一下 import numpy as np 一、np.random用法 生成随机整数:np.random.randint(low, high, size) low: 最小值high: 最大值size: 生成的数组大小(可以是多维,下面同理) 生成随机浮点数:np.random.uniform(low, …...
vue快速入门(十七)v-model数据双向绑定修饰符
注释很详细,直接上代码 上一篇 新增内容 v-model.trim 自动去除首尾空格v-model.number 自动转换成数字类型 源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" con…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...
