八、基于FPGA的以太网协议介绍(二)

在上一文中介绍了以太网的各层协议;链接:https://blog.csdn.net/weixin_41838250/article/details/114686428?spm=1001.2014.3001.5502

本文主要介绍一下我项目中使用的10G-BASE-R和MAC层的具体应用;因为项目需求,直接组装了MAC数据报;然后传输。

1.10G-BASE-R

1.1   内部结构:

设计使用了Xilinx的 ten_gig_eth_pcs_pma_0 IP实现10G-BASE-R;

用户接口:XGMII

PCS:64b/66b编解码,接收路径还包括块同步、解码器、译码器和误码(比特错误率)监控;

外部端口:底层使用了serdes高速串行通道;

1.2 核配置

1:数据位宽选择:如果用32bit,则用户数据时钟为312.5Mhz;64bit,则用户数据时钟为156.25Mhz;

2:寄存器配置端口:如果选择,则使用串行MDIO进行配置;不选择则使用并口的寄存器直接赋值;笔者用FPGA,直接给寄存器赋值。

这一页:主要选择是使用核设计还是参考例程;两者区别是时钟,复位模块在内部还是在外部。笔者设计需要4个10G然后组成40G网络,因此使用的是参考例程;共用一个时钟模块。

1.3寄存器介绍

使用并口配置,共536bit位;详细介绍可见ug068 26页

关键位说明:

0位:PMA Loopback Enable;1-使能,0-不使能;

15位:PMA Reset;1-复位,0-正常;

16位:Global PMD TX Disable;0-使能,1-不使能;

110位:PCS Loopback Enable;1-使能,0-不使能;

111位:PCS Reset;1-复位,0-不复位;

512位:PMA link status;link状态

516位:PCS link 配置;1-link up 0-link down

2.MAC核

2.1内部结构

   用户接口:AXI4-stream,接收,发送;

   MAC与物理层互联端口:XMGII;

   配置端口:AXI-Lite,配置到MDIO;

2.2 核配置

1,用户数据位宽:和物理层时钟,位宽匹配;

2,寄存器配置:如果选择,则使用AXI进行配置MDIO,这里没有使用;

3,互联端口:internal或XGMII端口,内部和外部;SDR和DDR的区别;笔者这里接的是从内部10G-BASE-R核出来的端口,因此选择的是内部。

这一页:主要选择是使用核设计还是参考例程;两者区别是时钟,复位模块在内部还是在外部。笔者设计需要4个10G然后组成40G网络,因此使用的是参考例程;共用一个时钟模块。

2.3 寄存器介绍

发送配置寄存器

0位:Transmitter Reset,发送控制器复位;1-复位,0-正常;

1位:Transmitter Enable,发送使能;1-使能,0-不使能;

2位:Transmitter VLAN Enable,VLAN帧发送使能;1-使能,0-不使能;

3位:Transmitter In-Band FCS Enable,CRC校验选择;1-由用户填充,0-核计算填充;

4位:Transmitter Jumbo Frame Enable,巨型帧发送使能;1-使能巨型帧,0-合法帧;

5位:Transmit Flow Control Enable,流控使能;1-由pause_req控制数据流,0-pause_req无效;

7位:Transmitter Preserve Preamble Enable,前导码选择;1-用户填充,0-核根据标准填充;

8位:Transmitter Interframe Gap Adjust Enable,帧间隙;1-使用tx_ifg_delay端口设置间隙,0-使用最小间隙;

9位:Transmitter LAN/WAN Mode,模式选择;1-发送器自动在帧间间隙中插入空闲数据,以将平均数据速率降低到OC-192 SONET有效负载速率(WAN模式),0-发送器使用标准以太网帧间间隙(局域网模式)。

14位:TX MTU Enable,MTU使能;1-TX MTU 作为发送最大帧,0-启用别的配置。

[30:16]位:TX MTU Size,TX MTU填入帧大小;

31位:Stacked VLAN mode enable:VLAN 标识使能;1-使能,0-不使能;

[79:32]位:发送器源MAC地址。

接收配置寄存器

0位:Receive Reset,接收控制器复位;1-复位,0-正常;

1位:Receive Enable,接收使能;1-使能,0-不使能;

2位:Receive VLAN Enable,VLAN帧接收使能;1-使能,0-不使能;

3位:Receive In-Band FCS Enable,CRC校验选择;1-校验传给用户,0-核校验丢弃;

4位:Receive Jumbo Frame Enable,巨型帧接收使能;1-使能巨型帧,0-合法帧;

5位:Receive Flow Control Enable,流控使能;1-由pause_req控制数据流,0-pause_req无效;

7位:Receive Preserve Preamble Enable,前导码选择;1-前导码给用户,0-丢弃;

8位:Receiver Length/Type Error Disable,长度/类型字段检查使能;1-不检查,0-检查;

9位:Control Frame Length Check Disable,帧长检查;1-不检查,如果帧长不合法,同样保留数据给用户;

14位:RX MTU Enable,MTU接收使能;1-RX MTU 作为接收最大帧,0-启用别的配置。

15位:Enhanced VLAN mode enable,VLAN字段检查使能;1-使能,0-不使能;

[30:16]位:RX MTU Size,TX MTU填入帧大小;

31位:Stacked VLAN mode enable:VLAN 标识使能;1-使能,0-不使能;

[79:32]位:接收送器源MAC地址。

3 系统设计

3.1架构如下:

3.2 模块代码如下:

net顶层模块

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2020/08/24 18:10:32
// Design Name: 
// Module Name: net_10g_warp
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module net_40g_warp #(
    parameter [47:0] src_mac_addr = 48'h111111_22222,
    parameter [47:0] dest_mac_addr = 48'h333333_444444
)(
    input          sys_clk,
    input          sys_rst,
    input          net_clk_p,
    input          net_clk_n,
 
    input          con_pma_loop,   
    output [3:0]   ot_tx_resetdone,
    output [3:0]   ot_rx_resetdone,
    output [31:0]  ot_core_status,
    output [255:0] ot_xgmii_txd,
    output [31:0]  ot_xgmii_txc,
    output [255:0] ot_xgmii_rxd,
    output [31:0]  ot_xgmii_rxc,
    output [3:0]   ot_axis_tvalid,
    output [3:0]   ot_axis_tlast,
    output [31:0]  ot_axis_tkeep,
    output [255:0] ot_axis_tdata,
    output [3:0]   ot_axis_align_flag,
    output [3:0]   ot_maxis_tready,
    output [31:0]  ot_xmgii_flow_cnt,
    output [31:0]  ot_xmgii_flow_data,

    output [3:0]   txp,
    output [3:0]   txn,
    input  [3:0]   rxp,
    input  [3:0]   rxn,
    
    output         xgmii_clk,
    output         xgmii_rst, 
    output [3:0]   xgmii_locked,
        
    output [3:0]   tx_tready,
    input  [3:0]   tx_tvalid,
    input  [3:0]   tx_tlast,
    input  [31:0]  tx_tkeep,
    input  [3:0]   tx_tuser,
    input  [255:0] tx_tdata,
    
    output [3:0]   rx_tvalid,
    output [3:0]   rx_tlast,
    output [31:0]  rx_tkeep,
    output [255:0] rx_tdata
);

   

    wire [3:0] rx_resetdone;
    wire [3:0] tx_resetdone;
    wire [31:0] core_status;
     
    wire [255:0] xgmii_txd;
    wire [31:0]  xgmii_txc;
    wire [255:0] xgmii_rxd;
    wire [31:0]  xgmii_rxc;
    
    wire [3:0]   axis_tvalid;
    wire [3:0]   axis_tlast;
    wire [31:0]  axis_tkeep;
    wire [255:0] axis_tdata;
        
    assign xgmii_rst =!(tx_resetdone[0] && rx_resetdone[0] 
                                  && tx_resetdone[1] && rx_resetdone[1] 
                                  && tx_resetdone[2] && rx_resetdone[2] 
                                  && tx_resetdone[3] && rx_resetdone[3]);
    
    assign xgmii_locked[0] = core_status[7:0] ? 1'b1 : 1'b0;
    assign xgmii_locked[1] = core_status[15:8] ? 1'b1 : 1'b0;
    assign xgmii_locked[2] = core_status[23:16] ? 1'b1 : 1'b0;
    assign xgmii_locked[3] = core_status[31:24] ? 1'b1 : 1'b0;
    
    eth_psc_pma_ip eth_psc_pma_ip_inst(
        .sys_clk        (sys_clk        ),    
        .sys_rst        (sys_rst        ),         
        .refclk_p       (net_clk_p      ),
        .refclk_n       (net_clk_n      ),
        
        .rx_resetdone_out(rx_resetdone  ),
        .tx_resetdone_out(tx_resetdone  ),
        
        .xgmii_clk      (xgmii_clk      ),
        .xgmii_txd      (xgmii_txd      ),
        .xgmii_txc      (xgmii_txc      ),
        .xgmii_rxd      (xgmii_rxd      ),
        .xgmii_rxc      (xgmii_rxc      ),
        
        .txp            (txp       ),
        .txn            (txn       ),
        .rxp            (rxp       ),
        .rxn            (rxn       ),
        
        .sim_speedup_control(0),
        .core_status    (core_status ),
        .config_vector  ({136'd0,16'h4c4b,383'd0,con_pma_loop}),
        .status_vector  ( ),
        .pma_pmd_type   (3'b101)
    );
    
    eth_mac_ip eth_mac_ip_inst(
        .xgmii_clk      (xgmii_clk      ),
        .xgmii_rst      (xgmii_rst      ),        
        .xgmii_locked   (xgmii_locked   ),
        .tx_aresetn     (xgmii_locked   ),
        .rx_aresetn     (xgmii_locked   ),
        
        .tx_tready      (tx_tready      ),
        .tx_tvalid      (tx_tvalid      ),
        .tx_tlast       (tx_tlast       ),
        .tx_tkeep       (tx_tkeep       ),
        .tx_tuser       (tx_tuser       ),
        .tx_tdata       (tx_tdata       ),
                       
        .rx_tvalid      (axis_tvalid  ),
        .rx_tlast       (axis_tlast   ),
        .rx_tkeep       (axis_tkeep   ),
        .rx_tuser       (   ),
        .rx_tdata       (axis_tdata  ),
        
        .xgmii_txd      (xgmii_txd      ),
        .xgmii_txc      (xgmii_txc      ),
        .xgmii_rxd      (xgmii_rxd      ),
        .xgmii_rxc      (xgmii_rxc      ),
        
        .tx_con_vector  ({src_mac_addr, 32'h00000012}),
        .rx_con_vector  ({src_mac_addr, 32'h00000012})
    );

    eth_rx_align_design  #(
        .mac_addr       (src_mac_addr)
    )eth_rx_align_design(
        .sys_clk        (xgmii_clk  ),
        .sys_rst        (xgmii_rst  ),
        
        .ot_axis_align_flag (ot_axis_align_flag),
        .ot_maxis_tready (ot_maxis_tready),
        
        .saxis_tvalid   (axis_tvalid),
        .saxis_tlast    (axis_tlast ),
        .saxis_tkeep    (axis_tkeep ),
        .saxis_tdata    (axis_tdata ),
    
        .maxis_tvalid   (rx_tvalid    ),
        .maxis_tlast    (rx_tlast     ),
        .maxis_tkeep    (rx_tkeep     ),
        .maxis_tdata    (rx_tdata     )
    );                  
    
    reg        runtime_1s_flag = 0;
    reg [31:0] runtime_1s      = 0;
    reg [31:0] xmgii_flow_cnt  = 0;
    reg [31:0] xmgii_flow_data  = 0;
    
    always @ (posedge xgmii_clk) begin
        if(xgmii_rst) begin 
            runtime_1s_flag <= 0;
            runtime_1s      <= 0;
            end
        else if(runtime_1s >= 32'd156_250_000) begin
            runtime_1s <= 0;
            runtime_1s_flag <= 1;
            end 
        else begin 
            runtime_1s <= runtime_1s + 1;
            runtime_1s_flag <= 0;
            end 
    end 
    
    always @ (posedge xgmii_clk) begin 
        if(xgmii_rst) begin 
            xmgii_flow_cnt  <= 0;
            xmgii_flow_data <= 0;
            end
        else if(runtime_1s_flag) begin 
            xmgii_flow_cnt  <= 0;
            xmgii_flow_data <= xmgii_flow_cnt;
            end         
        else if(tx_tready[0] && tx_tready[0])begin 
            xmgii_flow_cnt  <= xmgii_flow_cnt + 8;
            xmgii_flow_data <= xmgii_flow_data;
            end      
        else begin 
            xmgii_flow_cnt  <= xmgii_flow_cnt;
            xmgii_flow_data <= xmgii_flow_data;
            end 
    end      
    
    assign  ot_tx_resetdone = tx_resetdone;
    assign  ot_rx_resetdone = rx_resetdone;
    assign  ot_core_status = core_status;
    assign  ot_xgmii_txd = xgmii_txd;
    assign  ot_xgmii_txc = xgmii_txc;
    assign  ot_xgmii_rxd = xgmii_rxd;
    assign  ot_xgmii_rxc = xgmii_rxc;
    
    assign  ot_axis_tvalid = axis_tvalid;
    assign  ot_axis_tlast  = axis_tlast;
    assign  ot_axis_tkeep  = axis_tkeep;
    assign  ot_axis_tdata  = axis_tdata;
    assign  ot_xmgii_flow_cnt  = xmgii_flow_cnt;
    assign  ot_xmgii_flow_data = xmgii_flow_data;
    
    
endmodule

MAC模块

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2020/08/24 15:51:05
// Design Name: 
// Module Name: eth_mac_ip
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module eth_mac_ip(
    input   xgmii_clk,
    input   xgmii_rst,    
    input   [3:0] xgmii_locked,
    input   [3:0] tx_aresetn,
    input   [3:0] rx_aresetn,
    
    output [3:0]   tx_tready,
    input  [3:0]   tx_tvalid,
    input  [3:0]   tx_tlast,
    input  [31:0]  tx_tkeep,
    input  [3:0]   tx_tuser,
    input  [255:0] tx_tdata,
    
    output [3:0]   rx_tvalid,
    output [3:0]   rx_tlast,
    output [31:0]  rx_tkeep,
    output [3:0]   rx_tuser,
    output [255:0] rx_tdata,
    
    output  [255:0] xgmii_txd,
    output  [31:0]  xgmii_txc,
    input [255:0] xgmii_rxd,
    input [31:0]  xgmii_rxc,
    
    input  [79:0]  tx_con_vector,
    input  [79:0]  rx_con_vector

);

    genvar i;      
    reg [7:0] tx_ifg_delay = 0;

generate
    for (i=0;i<4;i=i+1)
    begin : gt_gen        
    ten_gig_eth_mac_0 xgmac_i (
       .reset                   (xgmii_rst          ),
       .tx_axis_aresetn         (tx_aresetn[i]      ),
       .tx_axis_tdata           (tx_tdata[64*i+:64] ),
       .tx_axis_tvalid          (tx_tvalid[i]       ),
       .tx_axis_tlast           (tx_tlast[i]        ),
       .tx_axis_tuser           (tx_tuser[i]        ),
       .tx_axis_tkeep           (tx_tkeep[8*i+:8]   ),
       .tx_axis_tready          (tx_tready[i]       ),       
       .tx_ifg_delay            (tx_ifg_delay       ),
       .tx_statistics_vector    ( ),
       .tx_statistics_valid     ( ),
       .pause_val               (0),
       .pause_req               (0),
       .rx_axis_aresetn         (rx_aresetn[i]      ),
       .rx_axis_tdata           (rx_tdata[64*i+:64] ),
       .rx_axis_tkeep           (rx_tkeep[8*i+:8]   ),
       .rx_axis_tvalid          (rx_tvalid[i]       ),
       .rx_axis_tuser           (rx_tuser[i]        ),
       .rx_axis_tlast           (rx_tlast[i]        ),
       .rx_statistics_vector    ( ),
       .rx_statistics_valid     ( ),
       .tx_configuration_vector (tx_con_vector      ),
       .rx_configuration_vector (rx_con_vector      ),
       .status_vector           ( ),
       .tx_clk0                 (xgmii_clk          ),
       .tx_dcm_locked           (xgmii_locked[i]    ),
       .xgmii_txd               (xgmii_txd[64*i+:64]),
       .xgmii_txc               (xgmii_txc[8*i+:8]  ),
       .rx_clk0                 (xgmii_clk          ),
       .rx_dcm_locked           (xgmii_locked[i]    ),
       .xgmii_rxd               (xgmii_rxd[64*i+:64]),
       .xgmii_rxc               (xgmii_rxc[8*i+:8]  )
    );
    end
endgenerate     

endmodule

10GBASE-R模块

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2020/08/24 10:33:28
// Design Name: 
// Module Name: eth_psc_pma_ip
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module eth_psc_pma_ip(
    input          sys_clk,    
    input          sys_rst,         
    input          refclk_p,
    input          refclk_n,


    output [3:0]   tx_resetdone_out,
    output [3:0]   rx_resetdone_out,
    
    output         xgmii_clk,    
    input  [255:0] xgmii_txd,
    input  [31:0]  xgmii_txc,
    output [255:0] xgmii_rxd,
    output [31:0]  xgmii_rxc,
    
    output [3:0]    txp,
    output [3:0]    txn,
    input  [3:0]    rxp,
    input  [3:0]    rxn,
    
    input       sim_speedup_control,
    output [31:0]   core_status,
    input  [535:0]  config_vector,
    output [1791:0]  status_vector,
    input [2:0]     pma_pmd_type
);

    genvar i;  
  // Signal declarations
    wire coreclk;
    wire [3:0] txoutclk;
    wire qplloutclk;
    wire qplloutrefclk;
    wire qplllock;
  
    wire [3:0] tx_resetdone_int;
    wire [3:0] rx_resetdone_int;
  
    wire areset_coreclk;
    wire gttxreset;
    wire gtrxreset;
    wire qpllreset;
    wire txuserrdy;
    wire reset_counter_done;
  
    wire txusrclk;
    wire txusrclk2;
    wire refclk;
    wire [3:0] rxrecclk_out;

    assign tx_resetdone_out = tx_resetdone_int;
    assign rx_resetdone_out = rx_resetdone_int;   
    assign xgmii_clk = coreclk;
    
    ten_gig_eth_pcs_pma_0_gt_common # (
        .WRAPPER_SIM_GTRESET_SPEEDUP("TRUE") ) //Does not affect hardware
    ten_gig_eth_pcs_pma_gt_common_block(
        .refclk             (refclk         ),
        .qpllreset          (qpllreset      ),
        .qplllock           (qplllock       ),
        .qplloutclk         (qplloutclk     ),
        .qplloutrefclk      (qplloutrefclk  )
    );

    // Instantiate the 10GBASER/KR shared clock/reset block 
    ten_gig_eth_pcs_pma_0_shared_clock_and_reset ten_gig_eth_pcs_pma_shared_clock_reset_block(
        .areset             (sys_rst        ),
        .refclk_p           (refclk_p       ),
        .refclk_n           (refclk_n       ),
        .refclk             (refclk         ),
        .coreclk            (coreclk        ),
        .txoutclk           (txoutclk[0]       ),
        .qplllock           (qplllock       ),
        .areset_coreclk     (areset_coreclk ),
        .gttxreset          (gttxreset      ),
        .gtrxreset          (gtrxreset      ),
        .txuserrdy          (txuserrdy      ),
        .txusrclk           (txusrclk       ),
        .txusrclk2          (txusrclk2      ),
        .qpllreset          (qpllreset      ),
        .reset_counter_done (reset_counter_done)
    );
    
    generate
           for (i=0;i<4;i=i+1)
           begin : gt_gen
            ten_gig_eth_pcs_pma_0 ten_gig_eth_pcs_pma_i(
                .dclk               (sys_clk            ),
                .areset             (sys_rst            ),  
                
                .coreclk            (coreclk            ),
                .areset_coreclk     (areset_coreclk     ),    
                .qplllock           (qplllock           ),
                .qplloutclk         (qplloutclk         ),
                .qplloutrefclk      (qplloutrefclk      ),
                            
                .txoutclk           (txoutclk[i]        ),
                .txusrclk           (txusrclk           ),
                .txusrclk2          (txusrclk2          ),
                .txuserrdy          (txuserrdy          ),
                .rxrecclk_out       (rxrecclk_out[i]    ),
        
                .gttxreset          (gttxreset          ),
                .gtrxreset          (gtrxreset          ),
                .tx_resetdone       (tx_resetdone_int[i]),
                .rx_resetdone       (rx_resetdone_int[i]),
                .reset_counter_done (reset_counter_done ),
                
                .sim_speedup_control(sim_speedup_control),
                .pma_pmd_type       (pma_pmd_type       ),
                .configuration_vector(config_vector     ),
                .status_vector      (status_vector[448*i+:448]  ),
                .core_status        (core_status[8*i+:8]),
                .signal_detect      (1),
                .tx_fault           (0), 
                .tx_disable         ( ),
                
                .xgmii_txd          (xgmii_txd[64*i+:64] ),
                .xgmii_txc          (xgmii_txc[8*i+:8]   ),
                .xgmii_rxd          (xgmii_rxd[64*i+:64] ),
                .xgmii_rxc          (xgmii_rxc[8*i+:8]   ),
        
                .txp                (txp[i]             ),
                .txn                (txn[i]             ),
                .rxp                (rxp[i]             ),
                .rxn                (rxn[i]             ),
        
                .drp_req            ( ),
                .drp_gnt            (0),
                .drp_den_o          ( ),
                .drp_dwe_o          ( ),
                .drp_daddr_o        ( ),
                .drp_di_o           ( ),
                .drp_drdy_o         ( ),
                .drp_drpdo_o        ( ),
                .drp_den_i          (0),
                .drp_dwe_i          (0),
                .drp_daddr_i        (0),
                .drp_di_i           (0),
                .drp_drdy_i         (0),
                .drp_drpdo_i        (0)
            );
        end       
endgenerate   
endmodule

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值