从零开始 verilog 以太网交换机(二)MAC接收控制器的设计与实现

这篇具有很好参考价值的文章主要介绍了从零开始 verilog 以太网交换机(二)MAC接收控制器的设计与实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

从零开始 verilog 以太网交换机(二)MAC接收控制器的设计与实现



🔈声明:
😃博主主页:王_嘻嘻的CSDN主页
🧨 从零开始 verilog 以太网交换机系列专栏:点击这里
🔑未经作者允许,禁止转载,侵权必删
🚩关注本专题的朋友们可以收获一个经典交换机设计的全流程,包括设计与验证(FPGA);以太网MAC的基础知识。新手朋友们还将获得一个具有竞争力的项目经历,后续整个工程和代码下载链接也都会放在csdn和公众号内

  本章进行MAC控制器的设计与实现,共分为两个部分:接收控制器和发送控制器。整体架构可以参考:从零开始 verilog 以太网交换机(一)架构分析,本文将首先分析MAC接收控制器的设计。


1、MAC接收控制器功能

  MAC控制器负责以太网的MAC层和PHY层之间的数据交换,主要是根据MII标准接口规范进行数据收发
  对于本章的MAC接收控制器而言,其功能包括以下4点:

  • 识别接收数据帧的起始符;
  • 识别数据帧的字节边界,将半字节的数据转换为字节流;
  • 对数据帧长度进行计数,检测帧长度是否符合规范,CRC校验,并上报错误标识;
  • 存储数据帧的指针信息(规范标志、帧长度等);

2、MAC接收控制器接口

  MAC接收控制器一端连接标准MII(Media Independent Interface,媒体独立接口)接口,另一端连接交换机内部的数据帧处理单元。因为交换机的系统时钟 clk 和PHY的 rx_clk 为异步时钟,且而后级的数据处理单元最坏情况需要接收4 Port的数据帧传输,可能出现满载,来不及处理接收的数据,所以在MAC接收器内部,我们设计了异步FIFO,以完成数据缓冲的作用,另一方面FIFO也可以完成握手信号的逻辑,对MAC控制器内部的状态机进行反压

  所以,MAC接收控制器的输入为MII接口,输出为FIFO接口形式,由于FIFO比较基础,下面就仅罗列MII接口。

如何开发一个以太网交换机,从零开始ethernet switch,macos,fpga开发

①:MII接口为PHY<->MAC间接口的统称,本工程用了最原始的MII接口,随着速率要求还有GMII、SGMII、RGMII等多类MII接口,感兴趣的朋友可以自行了解。
②:复杂的硬件设计中模块间通常存在请求(request)和响应(response)的握手机制,当后级模块内部来不及处理数据时,会通知前级模块,禁止前级继续发送数据,并以此类推,直到数据流源头被暂停,这个行为就叫做反压。


3、MAC接收控制器实现细节

  根据以太网MAC层的规范,控制器还需要对数据帧进行CRC-32校验,由于CRC(Cyclic redundancy check,循环冗余校验)本质就是反馈多项式,和LFSR(linear feedback shift register,线性反馈移位寄存器)类似,在本专题就不展开介绍了,需要了解的朋友可以自行搜索学习,通常CRC的多项式公式可以直接通过生成器来生成。(CRC生成器将放在本号的资源栏中,有需要的可以下载,或者关注博主的公众号,也有下载链接

  综合上述FIFO和CRC的需求,最后MAC接收控制器的整体架构图如下:

如何开发一个以太网交换机,从零开始ethernet switch,macos,fpga开发

3.1、功能细节分析

  1. 传递正确的帧信息给后级,例如是错误帧,就可以直接读出并丢掉;这就需要2个FIFO一个存放数据,一个存放帧信息,两者并不是一 一对应的关系,一个帧信息可能对应多字节的数据帧
  2. 根据MII数据格式识别帧开始标志帧起始符帧结束标志
  3. 检测数据帧长度是否符合规范(64 bytes < length < 1518 bytes),否则都为错误帧;
  4. 检测数据帧是否byte对齐,如果从MII收到的数据量为奇数则为错误帧;
  5. CRC校验错误,标记为错误帧;

3.2、AFIFO设计

  MAC接收控制器中有两个FIFO,我们将存放数据的FIFO称作data_fifo,将存放状态的称作state_fifo。

  • 为了后级模块更为简单高效的处理数据,MAC控制器需要以字节的形式传递数据,故data_fifo的位宽为8-bits,具体深度一般会根据要求的性能进行设置,本项目中暂时将深度设为4k,能够
    存放2个最长帧。
  • 而state_fifo需要记录数据帧的帧长度(以便后级模块知道帧的边界)以及帧的错误信息,所以宽度设置为16-bits,具体格式如下图。考虑到data_fifo深度为4k,若全是最小帧可以存放64个,所以state_fifo的深度设置为64
如何开发一个以太网交换机,从零开始ethernet switch,macos,fpga开发

3.3、MAC接收器核心电路设计

  由于在发送端每个数据帧的末尾会插入CRC-32的计算值,这会使得在接收端每一个正确的数据帧的CRC校验值为一固定值,当不为此值时,即代表发生CRC error。在设计中,我们可以将该固定值设置为一个parameter,以便大家使用不同的多项式实现CRC。

  此外,我们通过检查数据帧的起始标志和结束标志,来判断帧边界,并不断记录数据帧的字节数,当到达结束标志后,检查数据长度是否合规,数据是否是字节对齐的,若发生错误则在state_fifo中记录,这样就完成了MAC接收控制器的所有功能。

如何开发一个以太网交换机,从零开始ethernet switch,macos,fpga开发

  需要注意的是数据帧的开始符按照MAC帧格式来看是0x10101011,其中前6位的101010是MAC前导符的延申。前导符是比特‘10’的集合,用于PHY serdes(串行器)做时钟恢复用(因为serdes的时钟和数据合并在一根数据线上,所以接收端需要做时钟恢复)。所以接收到0x1011即代表接收到有效数据帧(SFD,start frame describe)。

  另一点是MAC帧要求在帧与帧之间必须存在间隔,即一个数据帧发送完毕后rx_dv必定存在低电平时刻,所以在设计中,我们使用一个状态机来表示数据帧处于的不同状态,并用于控制各个变量,状态跳转图如下:


如何开发一个以太网交换机,从零开始ethernet switch,macos,fpga开发

  将状态机共分为4个状态:ST_SOF、ST_WAIT、ST_EOF、ST_DONE,分别对应等待MAC帧开始、等待帧起始符、等待MAC结束、将各信息传递至fifo

  • 当MAC帧开始,没有接收到SFD时,状态进入ST_WAIT,直到接收到SFD进入ST_EOF,或者rx_dv拉低,该帧为错误帧,回到ST_SOF。此外当data_fifo空间不足以容纳一个最大帧时,会停止接收任何帧,该帧会被丢弃;
  • 进入ST_EOF后,接收的数据都为有效数据,需要不断记录接收的字节数,且每收够1字节数据,就写入data_fifo中,直到接收到eof信号,数据帧结束,进入ST_DONE状态,进行数据帧的各类检错;
  • ST_DONE内,需要检查帧长度、byte align、CRC error,并将状态写入state_fifo中,下一拍回到ST_SOF,等待下一数据帧。

③:serdes是一种将并行数据转换成高速串行数据发送的技术,通常是数模混合设计,有相当多优点,所以也十分复杂。当前多数主流的物理接口都用到了serdes,包括PCI-e,以太网等。


3.4、MAC接收器代码

  控制器的设计并不复杂,Verilog代码将放在下面,Testbench就不展示了,有需要的可以等专题结束后在资源中下载,或者去我的公众号获得链接。


module mac_r(
//system interface
input           clk,
input           rst_n,
//MII interface
input           rx_clk,
input           rx_dv,
input   [3:0]   rx_d,
//mac-r - interface mux
input           data_fifo_rd,
output  [7:0]   data_fifo_dout,
input           state_fifo_rd,
output  [15:0]  state_fifo_dout,
output          state_fifo_empty
    );
    
parameter   CRC_RESULT = 32'hc704dd7b;
parameter   ST_SOF      = 4'b0001;
parameter   ST_WAIT     = 4'b0010;
parameter   ST_EOF      = 4'b0100;    
parameter   ST_DONE     = 4'b1000;

parameter   BCNT_MAX    = 1518;
parameter   BCNT_MIN    = 64;

reg             rx_dv_dly0;  //用于输入数据有效的采样    
reg             rx_dv_dly1;
reg     [3:0]   rx_d_dly0;
reg     [3:0]   rx_d_dly1;

//信号有效信号的上升沿表示帧开始,下降沿则表示帧结束
wire            sof;  //start of frame  帧开始标志    只能表示有MAC帧来了
wire            eof;  //end of frame    帧结束标志
wire            sfd;  //start frame decribe 帧起始符  sof不代表真正数据帧的开始,sdf才代表!
wire            mac_r_rdy; //表示mac_r当前有接收能力
//控制状态机
reg     [3:0]   cur_state;
reg     [3:0]   next_state;
//byte cnt变量
wire            bcnt_clr;   //清零信号
reg     [11:0]  bcnt;

reg             frame_vld;  //数据帧有效信号

//fifo
wire    [7:0]   data_fifo_din;     
wire            data_fifo_wr;
wire    [11:0]  data_fifo_wr_cnt;

reg     [15:0]  state_fifo_din;
reg             state_fifo_wr;
wire            state_fifo_full;

wire    [31:0]  crc_reg;

always @(posedge rx_clk or negedge rst_n)begin
    if(!rst_n)begin
        rx_dv_dly0 <= 1'b0;
        rx_dv_dly1 <= 1'b0;
        rx_d_dly0[3:0] <= 4'b0;
        rx_d_dly1[3:0] <= 4'b0;
    end
    else begin
        rx_dv_dly0 <= rx_dv;
        rx_dv_dly1 <= rx_dv_dly0;
        rx_d_dly0[3:0] <= rx_d[3:0];
        rx_d_dly1[3:0] <= rx_d_dly0[3:0];
    end
end
    
assign sof = !rx_dv_dly1 & rx_dv_dly0;
assign eof = rx_dv_dly1 & !rx_dv_dly0;
assign sfd = rx_dv_dly0 & (rx_d_dly0[3:0]==4'b1011);

//三段式状态机
always @(posedge rx_clk or negedge rst_n)begin
    if(!rst_n)
        cur_state[3:0] <= ST_SOF;
    else
        cur_state[3:0] <= next_state[3:0];
end

always @(*)begin
    case(cur_state[3:0])
        ST_SOF:     next_state[3:0] = (sof & mac_r_rdy) ? !sfd ? ST_WAIT : ST_EOF : ST_SOF;
        ST_WAIT:    next_state[3:0] = rx_dv_dly0 ? sfd ? ST_EOF : ST_WAIT : ST_SOF;
        ST_EOF:     next_state[3:0] = eof ? ST_DONE : ST_EOF;
        ST_DONE:    next_state[3:0] = ST_SOF;
        default:    next_state[3:0] = ST_SOF;
    endcase        
end

assign bcnt_clr = (sof & sfd) | (cur_state[3:0]==ST_WAIT & sfd);

always @(posedge rx_clk or negedge rst_n)begin
    if(!rst_n)
        bcnt[11:0] <= 12'b0;
    else if(bcnt_clr)
        bcnt[11:0] <= 12'b0;
    else
        bcnt[11:0] <= bcnt[11:0] + 12'b1;
end

always @(posedge rx_clk or negedge rst_n)begin
    if(!rst_n)
        frame_vld <= 1'b0;
    else if(cur_state[3:0]==ST_EOF & eof)
        frame_vld <= 1'b0;
    else if( (cur_state[3:0]==ST_SOF & sof & sfd) | (cur_state[3:0]==ST_WAIT & rx_dv_dly0 & sfd))
        frame_vld <= 1'b1;
end


assign data_fifo_wr = frame_vld & bcnt[0] & rx_dv_dly0; //当存够两个rx_data时,且帧有效时,向data_fifo中存一次数据
assign data_fifo_din = {rx_d_dly0,rx_d_dly1};


assign mac_r_rdy = (data_fifo_wr_cnt[11:0]> 4096 - BCNT_MAX);

always @(posedge rx_clk or negedge rst_n)begin
    if(!rst_n)
        state_fifo_wr <= 1'b0;
    else if(cur_state[3:0]==ST_EOF & eof)
        state_fifo_wr <= 1'b1;
    else
        state_fifo_wr <= 1'b0;
end

always @(posedge rx_clk or negedge rst_n)begin
    if(!rst_n)
        state_fifo_din[15:0] <= 16'b0;
    else if(cur_state[3:0]==ST_EOF & eof)begin
        state_fifo_din[10:0] <= bcnt[11:1];
        state_fifo_din[14] <=( (bcnt[11:1] > BCNT_MAX) | (bcnt[11:1] < BCNT_MIN) | bcnt[0] ) ? 1'b1 :1'b0;
        state_fifo_din[15] <= (crc_reg[31:0]==CRC_RESULT) ? 1'b0 : 1'b1;
    end
end


data_fifo x_data_fifo(
    .rst(~rst_n),
    .wr_clk(rx_clk),
    .rd_clk(clk),
    .din(data_fifo_din[7:0]),
    .wr_en(data_fifo_wr),
    .rd_en(data_fifo_rd),
    .dout(data_fifo_dout[7:0]),
    .full(),
    .empty(),
    .rd_data_count(),
    .wr_data_count(data_fifo_wr_cnt[11:0])
  );
  
state_fifo x_state_fifo(
    .rst(~rst_n),
    .wr_clk(rx_clk),
    .rd_clk(clk),
    .din(state_fifo_din[15:0]),
    .wr_en(state_fifo_wr),
    .rd_en(state_fifo_rd),
    .dout(state_fifo_dout[15:0]),
    .full(state_fifo_full),
    .empty(state_fifo_empty)
  );  

crc32 x_crc32(
    .clk(clk),
    .rst_n(rst_n),
    .data(data_fifo_din[7:0]),
    .init(sof),
    .cal(data_fifo_wr),
    .vld(data_fifo_wr),
    .crc_reg(crc_reg[31:0]),
    .crc()                //大端输出
    );

endmodule



文章来源地址https://www.toymoban.com/news/detail-804147.html


到了这里,关于从零开始 verilog 以太网交换机(二)MAC接收控制器的设计与实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 3.9、以太网交换机自学习和转发帧的流程

    1.以太网交换机工作在 数据链路层 (也包括 物理层 ) 说明:目前市场上也有包含 网络层 部分功能的交换机,称为 三层交换机 2.以太网交换机收到帧后,在帧交换表中查找 的 目 的 M A C 地 址 所 对 应 的 接 口 号 color{red}的目的MAC地址所对应的接口号 的 目 的 M A C 地 址

    2024年02月09日
    浏览(88)
  • 【网络设备】交换机的概念、工作原理、功能以及以太网帧格式

    个人主页: insist--个人主页​​​​​​ 本文专栏:网络基础——带你走进网络世界 本专栏会持续更新网络基础知识,希望大家多多支持,让我们一起探索这个神奇而广阔的网络世界。 目录 一、认识交换机 二、交换机的主要功能

    2024年02月10日
    浏览(49)
  • 【数通网络交换基础梳理1】二层交换机、以太网帧、MAC地址数据帧转发原理详解

    万年不变,先从模型结构分析,现在大家熟知的网络模型有两种。第一种是,OSI七层模型,第二种是TCP/IP模型。在实际运用中,参考更多的是TCP/IP模型。 OSI七层模型 TCP/IP模型 不需要全部理解,只需要明白两点:1、 数据包发送数据的过程是从上到下打包,接收数据是从下至上

    2024年02月03日
    浏览(61)
  • Hyper-v系列---【hyper-v添加虚拟以太网交换机连接时出错】

    我之前在上个地方住的时候,连的之前的wifi新建的虚拟机,搬家之后再打开,发现虚拟机连不上网了,刚开始以为虚拟交换机的问题,想新建一个虚拟交换机,发现老报“添加虚拟以太网交换机连接时出错”。经过一番尝试,发现是我连接的wifi处于共享状态的原因,取消连

    2024年02月03日
    浏览(54)
  • 实现VLAN间通信&以太网链路聚合与交换机堆叠、集群&华为ICT网络赛道

    使用路由器物理接口 路由器三层接口作为网关,转发本网段前往其它网段的流量。 路由器三层接口无法处理携带VLAN Tag的数据帧,因此交换机上联路由器的接口需配置为Access. 路由器的一个物理接口作为一个VLAN的网关,因此存在一个VLA就需要占用一个路由器物理接口。 路由

    2024年02月21日
    浏览(61)
  • 什么是数通技术?以太网交换机在数通技术中的精要

    数通技术是指数字通信技术,它涵盖了数字信号处理、数据传输、网络通信等领域。通信工程师在数通技术中负责设计、建设和维护数字通信系统,以实现可靠、高效的信息传输。这涉及到数字信号的编解码、调制解调、数据压缩、网络协议等方面的技术。数通技术在现代社

    2024年01月21日
    浏览(63)
  • 计算机网关原理、子网掩码原理(路由器、交换机)(网关:与以太网接口关联的路由)

    计算机网关(Computer Gateway)是指连接两个或多个不同网络的设备或系统。它可以是硬件设备(如路由器)或软件程序(如网络代理服务器),用于在不同网络之间进行数据传输和转发。网关的主要功能是将来自一个网络的数据包转发到另一个网络,并且能够处理不同网络之间

    2024年02月16日
    浏览(48)
  • Mellanox SX6036 40G/56G IB/以太网交换机基础配置以及开启web管理

    在19年的时候,笔者就购入了第一台6036,那时候还是在机缘巧合之下利用几台坏的才拼凑成的一个好的,在那时就已经进行了一番折腾,但是苦于没有手册,死活进不去web管理,最后还是花了一段时间才知道。 昨天,笔者刚刚刷完手上的第10台SX6036,心中十分感慨,于是便想

    2024年02月06日
    浏览(175)
  • 10.网桥是什么?网桥和路由器及交换机的区别?以太网和令牌环网,nat,查公网ip等

    网桥是什么?有什么作用? 网桥是一种网络设备,它可以在数据链路层(第二层)上连接不同的局域网(LAN),并根据MAC地址转发数据帧。网桥的作用是: 隔离碰撞域,提高网络性能和稳定性。 扩展网络范围,连接不同的网段或拓扑结构。 进行链路层的协议转换,实现不同

    2024年02月15日
    浏览(64)
  • 说明白STP的基本概念,生成树,以太网链路聚合与交换机堆叠,集群(HCLA-Datacom v1.0华为认证数通笔记4)

    在网路中部署生成树后,交换机之间会进行生成树协议报文的交互并进行无拓扑计算,最终讲网络中的某个(或某些)接口进行阻塞(block),从而打破环路。 原因是前面提到的二层环路带来的问题  带来的广播风暴和MAC地址漂移 而生成树能够动态响应2网络拓扑变化调整阻

    2024年02月02日
    浏览(51)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包