当前位置: 首页 > article >正文

10G_ethernet学习记录(1):10G Ethernet PCS/PMA ip的使用

参考资料:pg068:10G Ethernet PCS/PMA v6.0

开发平台:vivado2020.2

开发板卡:axck060(黑金板卡)

FPGA芯片:xcku060ffva_1156_2_i 

修改日志:

2024/11/30:仿真调通,添加仿真波形

0,基础知识:

了解XGMII,XAUI

XGMII:

  XGMII接口共74根连线,单端信号,采用HSTL/SSTL_2逻辑,端口电压1.5V/2.5V,由于SSTL_2的端口电压高,功耗大,现在已很少使用。HSTL即High Speed Transceiver Logic,高速发送逻辑的意思。SSTL,即Stub Series Terminated Logic,短路终止逻辑,主要用于高速内存接口,SSTL目前存在两种标准,SSTL_3是3.3V标准;SSTL_2是2.5V标准。
  主要包括三个部分。一是从MAC层到物理层的发送数据接口,二是从MAC层到物理层的接收数据接口,三是MAC层和物理层之间数据管理的MDIO/MDC接口

        74根线(参考千兆以太网的rxc,rxd[7:0],):RXD:32,RXC:4,RXLR:1;TXD:32,TXC:4,TXLR:1

XAUI:10 Gigabit attachment unit interface 10G附属单元接口

        由于受电气特性的影响,XGMII接口的PCB走线最大传输距离仅有7cm,并且XGMII接口的连线数量太多,给实际应用带来不便,因此,在实际应用中,XGMII接口通常被XAUI接口代替,XAUI即10 Gigabit attachment unit interface,10G附属单元接口,XAUI在XGMII的基础上实现了XGMII接口的物理距离扩展,将PCB走线的传输距离增加到50cm,使背板走线成为可能。
  源端XGMII把收发32位宽度数据流分为4个独立的lane通道,每个lane通道对应一个字节,经XGXS(XGMII Extender Sublayer)完成8B/10B编码后,将4个lane分别对应XAUI的4个独立通道,XAUI端口速率为:2.5Gbps * 1.25 * 4=12.5Gbps。
  在发送端的XGXS模块中,将TXD[31:0]/ RXD[31:0],TXC[3:0]/ RXC[3:0], TXC/ RXC转换成串行数据从TX Lane[3:0]/ RX Lane[3:0]中发出去,在接收端的XGXS模块中,串行数据被转换成并行,并且进行时钟恢复和补偿,完成时钟去抖,经过5B/4B解码后,重新聚合成XGMII。
  XAUI接口采用差分线,收发各四对,CML逻辑,AC耦合方式,耦合电容在10nF~100nF之间。
  XAUI接口可以直接接光模块,如XENPAK/X2等。也可以转换成一路10G信号XFI,接XFP/SFP+等。

1,手册阅读

我们使用的是PCS/PMA部分,基于Ultrascale系列。pg068包含7系列与Ultrascale。所以有些信号在不同的系列有不同的选择。比如user_clk,7系列中是core_clk,Ultrascale中是txuserclk_2。根据自己的需求进行区分。

 1.1 框架

xilinx提供两种:10GBASE-R(免费不要钱),10GBASE-KR(需要购买,背板)。我们选择使用10GBASE-R来实现10G以太网的PCS/PMA。

  • XGMII: 链接10千兆以太网MAC层(user_rtl)与PCS/PMA层(ip);
  • Transmit path,:包含 scrambler, 64b/66b encoder and Gearbox;(10G以太网是基于64/66编码来进行的);
  • Receive path: 包含 block synchronization, descrambler, decoder and BER (Bit Error Rate) monito ;(64//66对齐功能)

10G Ethernet PCS/PMA (ip)与user_logic(MAC)相连接,我们的目的是做MAC层。PCS/PMA交给IP核。

1.2 port_interface 

1.2.1 xgmii port

XGMII接口是FPGA内部的,不是与外部的PHY相连接(不用考虑走线之类的)。这个接口回用于IP核与用户编写的MAC层之间的连接。

rxd:64bit,参考时钟为156.25Mhz

rxd32bit,参考时钟为312.5Mhz

在FPGA中,要考虑时序问题,xilinx推荐的方式是大位宽,低时钟。所以使用rxd:64bit。 

1.2.2 optical module 

另外,该IP还提供了光模块接口。(不用自己编写o_sfp_disable了(。-ω-))

在官方example的tb文件中,signal_detect = 1'b1 , tx_fault = 1'b0;(这两个要给对,不然会pcs_rx_lock一直为未知状态,我在这里仿真卡了两天,重构之后按照example_prj才发祥这里给错了!!!!!)

开发板板卡的原理图中:

 mode0连接高电平,loss连接高电平。signal_detect = ~(mode0 || loss) = 0。

 1.2.3 MDIO接口(等待施工)

管理接口,未使用,先放着

 1.2.4 CLOCK and  RESET port

 在生成ip核时,勾选Include Shared Logic in example design。 可以更好地了解ip的时钟和复位逻辑。

 详细会在后续的example_prj学习中了解。

 有些时钟是7serial,有些时ultrascale系列。

1.2.5 10GBASE-KR Training Interface

KR版本,不是我们学习的目标。

 1.2.6 DRP interface port 

 drp控制接口,没用过。

1.2.7 Miscellaneous Ports(仿真相关)

这里面主要是sim_speedup_control用于加快仿真速度。

 注意,这个信号与srio中的仿真加速不一样。srio中直接使能就行。

在官方提供的tb文件中 ,

sim_speedup_control 先拉低,等待全局复位信号拉低之后,reset拉低之后。才拉高。

 我们还可以看到,在仿真加速中,对这个接口的描述。当我们想要implementation时(上板),只要不先拉低,再拉高。这个端口就不会作用。相应的,这个端口的作用条件就是先拉低,再拉高

1.2.8 configuration port

10G Ethernet PCS/PMA ip的配置端口是用了一个[535:0] configuration_vector大位宽矢量来控制的。

 

需要根据要求去查找对应控制目标。

我现在只使用了PMA Loopback Enable,PCS Loopback Enable。以及125us timer Control

Status Vector反应当前的状态

我们需要 PMA/PMD RX Link Status ,PCS RX Link Status 来判断接收端是否建立链接。

 

1.3 designing with the core

1.3.0 data_interface 

rxc = 0 ,表示数据位

rxc = 1 , 表示控制位,常用有开始FB,结束FD,错误FE,默认07。

64bit接口下,有两种开始帧(开始位置不一致,与64/66编码中一致)

1.S开始在8‘b0000_1000。

 

2,还有一种S在8‘b1000_0000。字节对齐发送。

1.3.1 clocking

数据位宽:64bit ;ultrascale系列时钟架构:

  1. 首先通过一个IBUFDS_GTE3将refclk_n,refclk_p转换为单端w_refclk信号。
  2. 因为10G ethernet的速度为10.3125,超过了cpll所能提供的速率,需要使用qpll,
  3. qpll产生的qpll_clk,qpll_refclk输入进GTE3中产生对应rxoutclk,txoutclk.
  4. rxoutclk,txoutclk使用bufg产生userclk,userclk2。

 XGMII接口的发送信号与txuserclk2是同步的!!!

1.3.2 reset 

1.3.3 mult core (后续施工)
1.3.4 loopback   (后续施工)

2,IP操作

2.1 生成10G Ethernet PCS/PMA ip核

配置如下:BASE-R是免费的。64bit大位宽。

勾选 include shared logic in example design

生成example_prj

2.2 example_pri学习

 生成的prj中包含如下模块:

1,gt_common_block:用于处理 gth模块;

用于产生qpllclk与qpllrefclk

module  ten_gig_eth_pcs_pma_0_gt_common # (
  parameter WRAPPER_SIM_GTRESET_SPEEDUP = "false" ) //Does not affect hardware
    (
     input  refclk,
     input  qpllreset,
     output qpll0lock,
     output qpll0outclk,
     output qpll0outrefclk
    );

 gt_common_block仿真波形

2,pcs_pma共享时钟,复位模块;

 仿真波形:

3,tb文件:官方编写的仿真顶层,包含一些仿真行为。施工中

3,编写工程

3.1 工程搭建 

整体工程如下:

vivado中架构:

 基本单元都是从example中参照过来的。

其中 

configuration_vector[535:0]
status_vector[447:0]

这两个模块,example中有详细的划分,结合手册选择自己所需要的。


   assign configuration_vector[0]   = pma_loopback;
   assign configuration_vector[14:1] = 0;
   assign configuration_vector[15]  = pma_reset;
   assign configuration_vector[16]  = global_tx_disable;
   assign configuration_vector[79:17] = 0;
   assign configuration_vector[83:80] = 0;
   assign configuration_vector[109:84] = 0;
   assign configuration_vector[110] = pcs_loopback;
   assign configuration_vector[111] = pcs_reset;
   assign configuration_vector[169:112] = test_patt_a_b;
   assign configuration_vector[175:170] = 0;
   assign configuration_vector[233:176] = test_patt_a_b;
   assign configuration_vector[239:234] = 0;
   assign configuration_vector[240] = data_patt_sel;
   assign configuration_vector[241] = test_patt_sel;
   assign configuration_vector[242] = rx_test_patt_en;
   assign configuration_vector[243] = tx_test_patt_en;
   assign configuration_vector[244] = prbs31_tx_en;
   assign configuration_vector[245] = prbs31_rx_en;
   assign configuration_vector[269:246] = 0;
   assign configuration_vector[271:270] = 0;
   assign configuration_vector[383:272] = 0;
   assign configuration_vector[399:384] = 16'h4C4B;
   assign configuration_vector[511:400] = 0;
   assign configuration_vector[512] = set_pma_link_status;
   assign configuration_vector[515:513] = 0;
   assign configuration_vector[516] = set_pcs_link_status;
   assign configuration_vector[517] = 0;
   assign configuration_vector[518] = clear_pcs_status2;
   assign configuration_vector[519] = clear_test_patt_err_count;
   assign configuration_vector[535:520] = 0;

   assign pma_link_status = status_vector[18];
   assign rx_sig_det = status_vector[48];
   assign pcs_rx_link_status = status_vector[226];
   assign pcs_rx_locked = status_vector[256];
   assign pcs_hiber = status_vector[257];
   assign teng_pcs_rx_link_status = status_vector[268];
   assign pcs_err_block_count = status_vector[279:272];
   assign pcs_ber_count = status_vector[285:280];
   assign pcs_rx_hiber_lh = status_vector[286];
   assign pcs_rx_locked_ll = status_vector[287];
   assign pcs_test_patt_err_count = status_vector[303:288];

3.2 仿真

在经过几天的调试之后,将仿真调通,更新仿真波形(2024/11/30)

 编写了一个数据生成模块,按照64bit的形式编写,每1000个周期trigger一次,发送一段固定的数据,并进行loopback,查看发送与接受的xgmii_data,xgmii_control是否一致。


module _10g_data_gen_test
(
    input                               i_xgmii_clk                ,
    input                               i_xgmii_rst                ,
    input              [  63:0]         i_xgnii_rxd                ,
    input              [   7:0]         i_xgmii_rxc                ,

    output             [  63:0]         o_xgmii_txd                ,
    output             [   7:0]         o_xgmii_txc                 
);

localparam                              P_TRAGER_GAP     =  1000   ;
localparam                              P_SEND_LEN      =   10     ;

reg                    [  63:0]         r_o_xgmii_txd              ;
reg                    [   7:0]         r_o_xgmii_txc              ;

reg                    [  15:0]         r_cnt                      ;
reg                                     r_triger                   ;
reg                    [  15:0]         r_triger_cnt               ;
reg                                     r_run                      ;

assign  o_xgmii_txd = r_o_xgmii_txd  ;
assign  o_xgmii_txc = r_o_xgmii_txc  ;

always @(posedge i_xgmii_clk) begin
    if (i_xgmii_rst) begin
        r_triger_cnt <= 'd0;
    end
    else if(r_triger_cnt == P_TRAGER_GAP - 1) begin
        r_triger_cnt <= 'd0;
    end
    else if(!r_run) begin
        r_triger_cnt <= r_triger_cnt + 1;
    end
    else begin
        r_triger_cnt <= 'd0;
    end
end

always @(posedge i_xgmii_clk) begin
    if (i_xgmii_rst) begin
        r_run <= 'd0;
    end
    else if(r_cnt == P_SEND_LEN - 1) begin
        r_run <= 'd0;
    end
    else if(r_triger) begin
        r_run <= 'd1;
    end
    else begin
        r_run <= r_run;
    end
end

always @(posedge i_xgmii_clk) begin
    if (i_xgmii_rst) begin
        r_triger <= 'd0;
    end
    else if(r_triger_cnt == P_TRAGER_GAP - 1) begin
        r_triger <= 'd1;
    end
    else begin
        r_triger  <= 'd0;
    end
end


always@(posedge i_xgmii_clk,posedge i_xgmii_rst)
begin
    if(i_xgmii_rst)
        r_cnt <= 'd0;
    else if(r_cnt == P_SEND_LEN - 1)
        r_cnt <= 'd0;
    else if(r_run || r_cnt)
        r_cnt <= r_cnt + 1;
    else
        r_cnt <= r_cnt;
end

always@(posedge i_xgmii_clk,posedge i_xgmii_rst)
begin
    if(i_xgmii_rst)
        r_o_xgmii_txd <= 64'h07070707_07070707;
    else if(!r_run)
        r_o_xgmii_txd <= 64'h07070707_07070707;
    else case(r_cnt)
        0           :r_o_xgmii_txd <= 64'hFB555555_55555555;
        1           :r_o_xgmii_txd <= 64'hD5000102_03040506;
        2           :r_o_xgmii_txd <= 64'h0708090a_0b0c0d0e;
        3           :r_o_xgmii_txd <= 64'h0f101112_13141516;
        4           :r_o_xgmii_txd <= 64'h1718191a_1b1c1d1e;
        5           :r_o_xgmii_txd <= 64'h1f202122_23242526;
        6           :r_o_xgmii_txd <= 64'h2728292a_2b2c2d2e;
        7           :r_o_xgmii_txd <= 64'h2f303132_33343536;
        8           :r_o_xgmii_txd <= 64'h3738393a_3b3c3d3e;
        9           :r_o_xgmii_txd <= 64'h3f404142_434445FD;
        default     :r_o_xgmii_txd <= 'd0;
    endcase
end

always@(posedge i_xgmii_clk,posedge i_xgmii_rst)
begin
    if(i_xgmii_rst)
        r_o_xgmii_txc <= 8'b1111_1111;
    else if(r_run && r_cnt == 0)
        r_o_xgmii_txc <= 8'b1000_0000;
    else if(r_run && r_cnt == 9)
        r_o_xgmii_txc <= 8'b0000_0001;
    else if(r_run)
        r_o_xgmii_txc <= 8'b0000_0000;
    else
        r_o_xgmii_txc <= 8'b1111_1111;
end


endmodule

另外,高速接口基本都有endian的变换,我们常用的是大端,gt常用的为小端。注意查看exp仿真。我编写了两个转换函数,是可以综合的,如下:

function [63:0] transfer_data;
    input              [  63:0]         i_ori_data                 ;
    begin
        transfer_data[7 :0 ] = i_ori_data[63:56];
        transfer_data[15:8 ] = i_ori_data[55:48];
        transfer_data[23:16] = i_ori_data[47:40];
        transfer_data[31:24] = i_ori_data[39:32];
        transfer_data[39:32] = i_ori_data[31:24];
        transfer_data[47:40] = i_ori_data[23:16];
        transfer_data[55:48] = i_ori_data[15:8 ];
        transfer_data[63:56] = i_ori_data[7 :0 ];
    end
endfunction


function [7:0] transfer_rxc;
    input              [   7:0]         i_ori_char                 ;
    begin
        transfer_rxc[0] = i_ori_char[7];
        transfer_rxc[1] = i_ori_char[6];
        transfer_rxc[2] = i_ori_char[5];
        transfer_rxc[3] = i_ori_char[4];
        transfer_rxc[4] = i_ori_char[3];
        transfer_rxc[5] = i_ori_char[2];
        transfer_rxc[6] = i_ori_char[1];
        transfer_rxc[7] = i_ori_char[0];
    end
endfunction

传输波形:

 

接受波形 :

 我进行了endian变换,用于后续的mac处理。

3.3上板

等待网卡中,上板之后更新。。。 


http://www.kler.cn/a/455877.html

相关文章:

  • 大语言模型(LLM)中大数据的压缩存储及其重要性
  • Day8补代码随想录 字符串part1 344.反转字符串|541.反转字符串II|卡码网:54.替换数字
  • Go+chromedp实现Web UI自动化测试
  • 【AIGC篇】AIGC 引擎:点燃创作自动化的未来之火
  • 基础8:可调用对象类型
  • 校史馆云展厅适合远程教学吗?
  • 【深度学习基础|pip安装】pip 安装库时,能够自动下载、安装、更新和卸载 Python 包,为基于python语言构建深度学习网络提供了方便。
  • CSS实现无限滚动的列表
  • docker redis安装
  • DWD三种事实表建模方法和注意事项
  • SQL中的TRIM用法
  • Scratch教学作品 | 鲁道夫与雪人——温馨圣诞动画,享受节日魔法! ✨
  • ElementPlus 自定义封装 el-date-picker 的快捷功能
  • 【Golang 面试题】每日 3 题(三)
  • SpringBoot整合Canal+RabbitMQ监听数据变更
  • 【Unity3D】ECS入门学习(二)实例化预制体
  • k8s-node2 NotReady 节点NotReady如何解决?
  • 蓝桥杯——神奇的数组
  • 认识Linux的Bash
  • AppAgent 源码 (xml 解析)
  • Python机器学习笔记(十四、凝聚聚类和DBSCAN)
  • Java学习总路线 详细
  • .net core sdk 项目多版本切换
  • DataCap MongoDB Driver: 全面解析MongoDB在DataCap中的使用指南
  • JVM运行时数据区的详细解析
  • [Redis] 在Linux中安装Redis并连接图形化工具详细过程(附下载链接)