在上一文中介绍了以太网的各层协议;链接: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