基于Ultrascale+系列GTY收发器64b/66b编码方式的数据传输(一)——Async Gearbox使用及上板测试

  于20世纪80年代左右由IBM提出的传统8B/10B编码方式在编码效率上较低(仅为80%),为了提升编码效率,Dgilent Techologies公司于2000年左右提出了64b/66b编码并应用于10G以太网中。Xilinx GT手册中没有过多64b/66b编码介绍,这里本人主要参考(https://www.ieee802.org/3/10GEPON_study/public/july06/thaler_1_0706.pdf、https://grouper.ieee.org/groups/802/3/ae/public/mar00/walker_1_0300.pdf、https://www.ieee802.org/3/bn/public/mar13/hajduczenia_3bn_04_0313.pdf)三篇文献。本文对64B/66B编码方式、GTY IP核Aync Gearbox 64B/66B配置及使用方法进行介绍并进行仿真及上板测试。

64B/66B编码简介

  64B/66B仍采用突发数据传输的方式传输数据,一个完整的数据传输过程包含S(起始位)、D(数据位)、T(停止位)三种类型的字符,在空闲时刻,可以发送C / Z(控制类字符)。不同于8B/10B的是,64B/66B会对一个完整的数据流进行分割,变成几个64bit的蓝色小段。

图片

  几个蓝色小段的格式需要满足如下表格中的某一模式,64B/66B会对这些64bit的小段编码成66bit(加上2bit Sync字段)的数据。

图片

  如上图,64B/66B仍包括控制字符和数据字符两种字符,不同于8B/10B的是,数据传输的起始停止控制字符通过块类型字段隐形确定其类型及位置。其中起始控制字符只有位与第0字节和第5字节两种情况。

  完整的控制字符列表如下,其中不同协议所规定的控制字符标识有所不同,本文使用XGMII协议的控制字符:

图片

字节对齐(帧同步算法): 8B/10B的字节对齐通过划窗检测逗号K码进行,64B/66B的字节对齐方式与之类似,通过划窗检测有效Sync header同步头进行,有效同步头仅包含01和10两种类型,当识别到11或00无效同步头后,划窗进行下次判定。

  • 在连续识别到64个有效同步头后,确定帧同步完成,字节对齐

  • 在64个同步头中识别到16个无效同步头后,确定帧同步失效,重新进行同步

  • 在125us中出现任意16个错误后,认为帧同步无法实现,禁止帧同步。

图片

图片

防止字节对齐误判: 当TX发送的66bit报文过于特殊时,如{{8’h01, 8’h02, 8’h03, 8’h04, 8’h05, 8’h06, 8’h07, 8’h78, {8’h08, 8’h09, 8’h0a, 8’h0b, 8’h0c, 8’h0d, 8’h0e, 8’hff}},64B/66B字节对齐可能会出现在数据中位置,如下图所示,此时检测的同步始终为01和10,但得到的同步后的数据是错误的。

图片

  幸运的是,64/66bit报文通常需要进行加扰解扰操作(Scramble/Descramble),即在发送的数据中添加白噪声,当接收后去掉白噪声得到原始数据。

** 64B/66B加扰解扰:** 64B/66B加扰解扰的表达式为 X58 + X19 + 1 = 0,其具体实现方式可参考Xilinx GT示例工程。

图片

GTY的64B/66B配置方式

  对于64B/66B编码,GTY支持采用Async Gearbox和Sync Gearbox两种方式,两种方式的区别在于异步变速箱提供的用户时钟能够完美匹配64B的发送速率,不会出现每隔一段时间停发一次数据的情况,本文采用Async Gearbox方式进行实现。此外,由于64B/66B对64B数据进行编码,因此本文选择使用64bit的用户数据位宽。

图片

  64B/66B的字节对齐由用户逻辑进行判断,因此无法选择。在其他配置上,本文使用的配置与8B/10B配置相同,如仍选用QSFP1所在GT。

GTY 64B/66B的使用方法:

发送模块

  发送主要包含txheader_in_r、txsequence_in_r、gtwiz_userdata_tx_in_r三个信号,txheader_in_r用于填入同步头,gtwiz_userdata_tx_in_r用于填入待传输块数据,txsequence_in_r用于填入一个累加计数器,TX Async Gearbox相同于一个66bit转64bit的异步FIFO,txsequence_in_r用于TX Async Gearbox FIFO的写入数据计数。

  发送一个14字节数据包的代码如下:

    enum logic [3:0] {
        TX_RESET,
        TX_IDLE,
        TX_SEND_MIX_DATA,
        TX_SEND_DATA
    } tx_fsm_r, tx_fsm_s;

    always_comb begin
        case (tx_fsm_r)
        TX_RESET: begin
            if (gtwiz_reset_tx_done_out) begin
                tx_fsm_s = TX_IDLE;
            end else begin
                tx_fsm_s = TX_RESET;
            end
        end
        TX_IDLE: begin
            tx_fsm_s = TX_SEND_MIX_DATA;
        end
        TX_SEND_MIX_DATA: begin
            tx_fsm_s = TX_SEND_DATA;
        end
        TX_SEND_DATA: begin
            tx_fsm_s = TX_IDLE;
        end
        default: tx_fsm_s = TX_RESET;
        endcase
    end

    always_ff @(posedge gtwiz_userclk_tx_usrclk2_out) begin
        case (tx_fsm_s)
        TX_RESET: begin
            txheader_in_r <= 6'b0;
            gtwiz_userdata_tx_in_r <= 64'h0;
        end
        TX_IDLE: begin // C0C1C2C3/C4C5C6C7
            txheader_in_r[1:0] <= 2'b10;
            gtwiz_userdata_tx_in_r[63:0] <= {{7{XGMII_IDLE}}, 8'h1e};
        end
        TX_SEND_MIX_DATA: begin // S0D1D2D3/D4D5D6D7
            txheader_in_r[1:0] <= 2'b10;
            gtwiz_userdata_tx_in_r[63:0] <= {8'h01, 8'h02, 8'h03, 8'h04, 8'h05, 8'h06, 8'h07, 8'h78};  
        end
        TX_SEND_DATA: begin // D0D1D2D3/D4D5D6T7
            txheader_in_r[1:0] <= 2'b10;
            gtwiz_userdata_tx_in_r[63:0] <= {8'h08, 8'h09, 8'h0a, 8'h0b, 8'h0c, 8'h0d, 8'h0e, 8'hff};  
        end
        endcase
    end

接收同步模块

  接收同步模块按照前文所说同步算法进行实现,包含SYNC_OUT未同步和SYNC_IN同步完成两个状态。主要利用rxgearboxslip_in进行单比特划窗,以及rxheader_out检测同步头。

    enum logic [3:0] {
        RX_SYNC_RESET,
        RX_SYNC_OUT,
        RX_SYNC_IN
    } rx_sync_fsm_r, rx_sync_fsm_s;

    always_comb begin
        case (rx_sync_fsm_r)
        RX_SYNC_RESET: begin
            if (gtwiz_reset_rx_done_out) begin
                rx_sync_fsm_s = RX_SYNC_OUT;
            end else begin
                rx_sync_fsm_s = RX_SYNC_RESET;
            end
        end
        RX_SYNC_OUT: begin 
            if (rxheadervalid_out & ^rxheader_out[1:0] && valid_sync_headers_cnt_r == 6'd63) begin
                rx_sync_fsm_s = RX_SYNC_IN;
            end else begin
                rx_sync_fsm_s = RX_SYNC_OUT;
            end
        end
        RX_SYNC_IN: begin
            if (rxheadervalid_out & ~(^rxheader_out[1:0]) && invalid_sync_headers_cnt_r == 5'
                rx_sync_fsm_s = RX_SYNC_OUT;
            end else begin
                rx_sync_fsm_s = RX_SYNC_IN;
            end
        end
        default: rx_sync_fsm_s = RX_SYNC_RESET;
        endcase
    end

    always_ff @(posedge gtwiz_userclk_rx_usrclk2_out) begin
        case (rx_sync_fsm_s)
        RX_SYNC_RESET: begin
            valid_sync_headers_cnt_r <= 6'd0;
            invalid_sync_headers_cnt_r <= 4'd0;
            headers_cnt_r <= 6'd0;
            rxgearboxslip_in <= 1'b0;
        end
        RX_SYNC_OUT: begin
            if (rxheadervalid_out) begin
                if (^rxheader_out[1:0]) begin
                    valid_sync_headers_cnt_r <= valid_sync_headers_cnt_r + 6'd1;
                end else begin
                    valid_sync_headers_cnt_r <= 6'd0;
                    headers_cnt_r <= headers_cnt_r + 6'd1;
                end
            end

            if (rxheadervalid_out && headers_cnt_r == 6'd63) begin
                rxgearboxslip_in <= 1'b1;
            end else begin
                rxgearboxslip_in <= 1'b0;
            end
        end
        RX_SYNC_IN: begin
            valid_sync_headers_cnt_r <= 6'd0;
            if (rxheadervalid_out) begin
                if (~(^rxheader_out[1:0])) begin
                    invalid_sync_headers_cnt_r <= invalid_sync_headers_cnt_r + 6'd1;
                end else if (headers_cnt_r == 6'd63) begin
                    invalid_sync_headers_cnt_r <= 6'd0;
                end
                headers_cnt_r <= headers_cnt_r + 6'd1; 
            end

            rxgearboxslip_in <= 1'b0;
        end
        endcase
    end

接收模块

  接收同步模块输出采用AXI-Stream接口,主要根据rxheader_out_r、gtwiz_userdata_rx_out_r[7:0]进行查表,得出tkeep、tstrb、tlast、tvalid、tdata的相应值。

    enum logic [3:0] {
        RX_RESET,
        RX_RECV
    } rx_fsm_r, rx_fsm_s;

    always_comb begin
        case (rx_fsm_r)
        RX_RESET: begin
            if (rx_reset_flag_rr) begin
                rx_fsm_s = RX_RESET;
            end else begin
                rx_fsm_s = RX_RECV;
            end
        end
        RX_RECV: begin 
            rx_fsm_s = RX_RECV;
        end
        default: rx_fsm_s = RX_RESET;
        endcase
    end

    (* MARK_DEBUG= "true" *) logic [63:0] rx_data;
    (* MARK_DEBUG= "true" *) logic [7:0]  rx_keep;
    (* MARK_DEBUG= "true" *) logic [7:0]  rx_strb;
    (* MARK_DEBUG= "true" *) logic        rx_valid;
    (* MARK_DEBUG= "true" *) logic        rx_last;
       
    always_ff @(posedge gtwiz_userclk_rx_usrclk2_out) begin
        case (rx_fsm_s)
        RX_RESET: begin
            rx_data <= 64'h0;
            rx_keep <= 8'h0;
            rx_strb <= 8'h0;
            rx_valid <= 1'b0;
            rx_last <= 1'b0;
        end
        RX_RECV: begin
            if (rxheader_out_r[1:0] == 2'b10) begin
                case (gtwiz_userdata_rx_out_r[7:0])
                8'h78: begin            // S0D1D2D3/D4D5D6D7
                    rx_valid <= 1'b1;
                    rx_data <= {gtwiz_userdata_rx_out_r[63:8], 8'h0};
                    rx_keep <= 8'hff;
                    rx_strb <= 8'hfe;
                    rx_last <= 1'b0;
                end
                8'hff: begin            // D0D1D2D3/D4D5D6T7
                    rx_data <= {8'h0, gtwiz_userdata_rx_out_r[63:8]};
                    rx_keep <= 8'hff;
                    rx_strb <= 8'h7f;
                    rx_last <= 1'b1;
                end
                8'h1e: begin
                    rx_valid <= 1'b0;
                end
                endcase
            end else if (rxheader_out_r[1:0] == 2'b01) begin
                rx_data <= gtwiz_userdata_rx_out_r[63:0];
                rx_keep <= 8'hff;
                rx_strb <= 8'hff;
                rx_last <= 1'b0;
            end

        end
        endcase
    end

仿真测试

图片

上板测试

图片

完整代码

  完整代码可于同名公众号回复GTY_64B66B_SIMPLE下载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/553341.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

生活中的洪特规则

不知道你还记不记得高中物理所学的一个奇特的物理规则&#xff1a;洪特规则。 洪特规则是德国人弗里德里希洪特&#xff08;F.Hund&#xff09;根据大量光谱实验数据总结出的一个规律&#xff0c;它指出电子分布到能量简并的原子轨道时&#xff0c;优先以自旋相同的方式分别占…

【算法一则】矩阵置零 【矩阵】【空间复用】

题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例 2&#xff1a; …

深度学习 Lecture 9 信息增益、One-hot、回归树、集成树、随机森林、XGBoost模型

一、信息增益&#xff08;Information Gain) 决定使用什么特征来划分一个节点取决于什么样的特征选择最能减少熵&#xff08;也就是使纯度最大化&#xff09; 在决策树中&#xff0c;熵的减少被称为信息增益。 所以如何选择呢&#xff1f; 假设现在有三个特征可以选择&#…

CUDA 以及MPI并行矩阵乘连接服务器运算vscode配置

一、CUDA Vscode配置 &#xff08;一&#xff09;扩展安装 本地安装 服务器端安装 &#xff08;二&#xff09; CUDA 配置 .vscode c_cpp_properties.json {"configurations": [{"name": "Linux","includePath": ["${workspa…

【NUCLEO-G071RB】004——GPIO-按键EXTI外部中断控制LED闪烁

NUCLEO-G071RB&#xff1a;004——GPIO-按键EXTI外部中断控制LED闪烁 设计目标电路原理图芯片配置程序修改 设计目标 电路原理图 与NUCLEO-G071RB&#xff1a;003——GPIO-按键控制LED灯相同 芯片配置 1、PC13&#xff08;B1&#xff09;&#xff1a;EXTI外部中断模式&…

STM32 USB虚拟串口

电路原理图 usb部分 晶振部分 usb与单片机连接 配置信息 sys配置信息 rcc配置信息 usb配置信息 虚拟串口配置信息 时钟配置信息 项目配置信息 代码 包含文件 主函数代码 实验效果 修改接收波特率依然可以正常接收&#xff0c;也就是说单片机可以自动适应上位机的波特率设置。…

【Day 1】HTML 与 CSS

1 前端 网站的工作流程&#xff1a; 首先我们需要通过浏览器访问发布到前端服务器中的前端程序&#xff0c;这时候前端程序会将前端代码返回给浏览器浏览器得到前端代码&#xff0c;此时浏览器会将前端代码进行解析&#xff0c;然后展示到浏览器的窗口中&#xff0c;这时候我…

EVI增强型植被指数

​随着遥感技术的发展&#xff0c;我们对地球上的植被状况有了更深入的了解&#xff0c;而其中一种重要的工具就是EVI&#xff08;Enhanced Vegetation Index&#xff0c;增强型植被指数&#xff09;。EVI不仅是一种植被指数&#xff0c;更是一种对植被生态系统健康和生产力评估…

统一SQL-支持unpivot列转行

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库&#xff1a;Oracle 目标数据库&#xff1a;TDSQL-MySQL 操作目标 在Oracle中&#xff0c;可以使用unpivot将列转换成行&#xff0c;在TDSQL-MySQL中没有对应的功能&#xff0c;由…

设计模式学习(六)——《大话设计模式》

设计模式学习&#xff08;六&#xff09;——《大话设计模式》 简单工厂模式&#xff08;Simple Factory Pattern&#xff09;&#xff0c;也称为静态工厂方法模式&#xff0c;它属于类创建型模式。 在简单工厂模式中&#xff0c;可以根据参数的不同返回不同类的实例。简单工厂…

C++算法题 - 矩阵

目录 36. 有效的数独54. 螺旋矩阵48. 旋转图像73. 矩阵置零289. 生命游戏 36. 有效的数独 LeetCode_link 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现…

【IoTDB 线上小课 02】开源增益的大厂研发岗面经

还有友友不知道我们的【IoTDB 视频小课】系列吗&#xff1f; 关于 IoTDB&#xff0c;关于物联网&#xff0c;关于时序数据库&#xff0c;关于开源...给我们 5 分钟&#xff0c;持续学习&#xff0c;干货满满~ 5分钟学会 大厂研发岗面试 之前的第一期小课&#xff0c;我们听了 I…

SpringMVC(二)【请求与响应】

0、测试环境 我们简化开发&#xff0c;创建一个简单的环境&#xff08;因为没有其它包比如 service、dao&#xff0c;所以这里不用 Spring 容器&#xff0c;只用 SpringMVC 容器&#xff09;&#xff1a; Servelet 容器配置&#xff1a; package com.lyh.config;import org.s…

jmeter及PTS压测介绍和使用

一、常用压测工具&#xff1a; loadrunner apache ab&#xff08;单接口压测最方便&#xff09; jmeter 阿里云PTS&#xff08;原生上传jmeter脚本进行压测&#xff09; 二、jmeter可以压测不同的协议和应用 web http https jdbc for database TCP 三、使用场景及优点 1、功能…

飞行机器人专栏(十四)-- Kinect DK 人体骨骼点运动提取方法

系列文章目录 Ubuntu 18.04/20.04 CV环境配置&#xff08;下&#xff09;--手势识别TRTposeKinect DK人体骨骼识别_ubuntu kinect骨骼测试-CSDN博客文章浏览阅读1.3k次。trt_pose_ros kinect实现手势识别和人体骨骼识别&#xff0c;用于机器人运动控制参考_ubuntu kinect骨骼测…

SpringCloud(一)

微服务框架 一、分布式架构 分布式架构︰根据业务功能对系统进行拆分&#xff0c;每个业务模块作为独立项目开发&#xff0c;称为一个服务。 优点: 降低服务耦合有利于服务升级拓展 微服务是一种经过良好架构设计的分布式架构方案&#xff0c;微服务架构特征: 单一职责:微…

【函数式接口使用✈️✈️】通过具体的例子实现函数结合策略模式的使用

目录 前言 一、核心函数式接口 1. Consumer 2. Supplier 3. Function,> 二、场景模拟 1.面向对象设计 2. 策略接口实现&#xff08;以 Function 接口作为策略&#xff09; 三、对比 前言 在 Java 8 中引入了Stream API 新特性&#xff0c;这使得函数式编程风格进…

数据库工具解析之 OceanBase 数据库导出工具

背景 大多数的数据库都配备了自己研发的导入导出工具&#xff0c;对于不同的使用者来说&#xff0c;这些工具能够发挥不一样的作用。例如&#xff1a;DBA可以使用导数工具进行逻辑备份恢复&#xff0c;开发者可以使用导数工具完成系统间的数据交换。这篇文章主要是为OceanBase…

编曲知识20:人声和声处理 分轨导出 总线处理

和声处理 和声 声像注意不要和主旋律重叠 各个效果器的处理幅度可以更大 呼吸音可直接去掉 尽量不要和主旋律共用一个混响延迟轨 注意音量、注意主次 和声拓展-模拟合唱 录制两轨同八度的主旋律或低八度高八度的主旋律 声像左右分配 音量拉低 将各个合唱轨进行失真处理 …

【Pytorch】VSCode实用技巧 - 默认终端修改为conda activate pytorch

VScode修改配置使得启动终端为conda环境 VScode跑项目&#xff0c;在启动pytorch项目时往往会有千奇百怪的问题&#xff0c;最常见的就是显示“conda activate pytorch”后会要求“conda init”&#xff0c;但输入后实际上也不行&#xff0c;这是因为VSCode默认终端为 Powersh…