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

  基于Ultrascale+系列GTY收发器64b/66b编码方式的数据传输(一)——Async Gearbox使用及上板测试 一文介绍了64B/66B编码方式及如何使用GTY IP核提供的Async Gearbox进行64B/66B数据传输,由于Async Gearbox方式下无法使用buffer bypass方式提供的低延时,因此本文介绍另一种64B/66B实现方式Sync Gearbox的使用方法。

Sync Gearbox原理

  Sync Gearbox相当于一个不同位宽的同步FIFO,TX端的Sync Gearbox用于将输入的66bit数据(2bit同步头+64bit数据(TX_DATA_WIDTH))转换为64bit位宽(TX_INT_DATAWIDTH)的输出数据。为了带宽匹配,每输入32个周期的66bit到Sync Gearbox,都需要33个周期通过64bit从Sync Gearbox输出。因此Sync Gearbox每隔33个周期都会有一个周期不存储输入的数据。

图片

  同样的,在RX端的Sync Gearbox用于将输入的64bit位宽(RX_INT_DATAWIDTH)转换为66bit数据(2bit同步头+64bit数据(RX_DATA_WIDTH))的输出数据,为了带宽匹配,每输入33个周期的64bit到Sync Gearbox,都需要32个周期通过66bit从Sync Gearbox输出。因此Sync Gearbox每隔33个周期都会有一个周期不输出有效的数据。

图片

  在具体实现上,Sync Gearbox的输入及输出位宽存在多种选择,不同方式在相隔多少个周期停顿一个周期、以及每隔多少周期向FIFO/从FIFO中读取一个数据两个方面存在区别。以外部数据位宽与内部数据位宽均为64情况为例,发送数据每两个TXDEQUENCE时钟周期变化一次,每发送32个数据后都需要暂停一次发送新的数据。

图片

GTY IP核配置

  GTY的配置方式与Async Gearbox类似,这里为了便于逻辑实现,采用外部数据位宽为64,内部数据位宽为32的方式。

图片

代码编写

发送部分

  发送主要用到txheader_in_r、txsequence_in_r、gtwiz_userdata_tx_in_r三个变量,不同点在于txheader_in_r需要在txsequence_in_r计数到32时的数据无效,即令TX发送端不认为txheader_in_r此时发送了数据。

    assign txsend_stop_s = (&txsequence_in_r[4:0]) == 1'b1 ? 1'b1 : 1'b0; // 31

    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
            if (txsend_stop_s) begin
                tx_fsm_s = TX_IDLE;
            end else begin
                tx_fsm_s = TX_SEND_MIX_DATA;
            end
        end
        TX_SEND_MIX_DATA: begin
            if (txsend_stop_s) begin
                tx_fsm_s = TX_SEND_MIX_DATA;
            end else begin
                tx_fsm_s = TX_SEND_DATA;
            end
        end
        TX_SEND_DATA: begin
            if (txsend_stop_s) begin
                tx_fsm_s = TX_SEND_DATA;
            end else begin
                tx_fsm_s = TX_IDLE;
            end
        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
            txsequence_in <= 7'b0;
            txsequence_in_r <= 7'b0;
        end
        default: begin
            txsequence_in <= txsequence_in_r;
            txsequence_in_r[6:6]  <= 1'b0;
            if (txsequence_in_r[5] == 1'b1) begin
                txsequence_in_r[5:0] <= 6'd0;
            end else begin
                txsequence_in_r[5:0]  <= txsequence_in_r[5:0] + 'd1;
            end
        end
        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
            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
            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
            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

    always_ff @(posedge gtwiz_userclk_tx_usrclk2_out) begin
        if (~txsend_stop_s) begin
            txheader_in <= txheader_in_r;
        end
    end

接收部分

  接收主要用到rxgearboxslip_in、rxdatavalid_out、rxheader_out、rxheadervalid_out,其中rxdatavalid_out与rxheadervalid_out为不同于Async Gearbox的信号,他们用于指示fifo是否读空,即此时输出的数据要当做无效数据处理。

  帧同步过程与接收部分与Async Gearbox时用到的方法类似,只是需要在header_valid为无效状态时暂停同步相关计数器计数。

    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
       
    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 (rxheadervalid_out[0]) 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 else begin
                rx_keep <= 8'h00;
                rx_strb <= 8'h00;
            end
        end
        endcase
    end

仿真结果

图片

上板测试

图片

完整代码

  本文所涉及代码可于同名公众号回复GTY_64B66B_SYNC获取。

  • 28
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wjh776a68

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值