自学内容网 自学内容网

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

  在GTY IP核的编码配置模式中,除了前几篇文章提到模式(都称为普通模式(normal mode),还有一类特殊但不难懂的模式CAUI模式,本文继续在64B66B Sync Gearbox基础上,说明64B66B Sync Gearbox(CAUI mode)模式的使用方式,并进行上板测试。

CAUI模式简介

  CAUI模式与普通模式的区别从以下两张来自GTY手册的CAUI框图可以看出。个人理解它通过时分复用的方式,通过MUX选择器支持两个数据流的独立收发。

图片

图片

  相比正常模式,CAUI模式将发送及接收一个8字节位宽的数据流拆分成发送及接收两个4字节位宽的数据流A和B,每个数据流可以负责的64B/66B 或 64B/ 67B(编码必须相同)数据业务传送,两者彼此独立。

图片

  在64B/66B模式下,数据流A使用TXHEADER的[1:0]以及TXDATA的[31:0],数据流B使用TXHEADER的[4:3]以及TXDATA的[63:32],两者只共享TXSEQUENCE信号。如下图所示,当TXSEQUENCE为31、32时,均需要暂停数据发送。

图片

  在接收侧的同步头对齐模块上,对于数据流A和B,分别具有各自的同步头,检测算法分别对各自的同步头进行检测,若数据流A(rxheader[2:0])未同步,则控制RXGEARBOXSLIP滑动,若数据流B(rxheader[5:3])未同步,则控制RXSLIDE滑动。

  在接收模块上,通过时分复用的方式,GTY输出的8字节位宽数据流的高低4字节各构成一个完整数据流,通过各自的处理模块进行解析。

图片

CAUI模式使用

  本文以Sync Gearbox 64B/66B方式为例进行说明,配置如下。

图片

  下面代码以处理数据流A过程为例,处理数据流B逻辑类似。

发送模块

  发送模块重复发送14字节数据包,与前文方式一致。

    always_ff @(posedge gtwiz_userclk_tx_usrclk2_out) begin
        case (tx_fsm_A_s)
        TX_RESET: begin
            txheader_in_A_r <= 2'b0;
            gtwiz_userdata_tx_in_A_r <= 64'h0;
        end
        TX_IDLE: begin
            txheader_in_A_r[1:0] <= 2'b10;
            gtwiz_userdata_tx_in_A_r[31:0] <= {{3{XGMII_IDLE}}, 8'h1e};
        end
        TX_IDLE_2: begin
            txheader_in_A_r[1:0] <= 2'b10;
            gtwiz_userdata_tx_in_A_r[31:0] <= {{4{XGMII_IDLE}}};
        end
        TX_SEND_MIX_DATA: begin
            txheader_in_A_r[1:0] <= 2'b10;
            gtwiz_userdata_tx_in_A_r[31:0] <= {8'h05, 8'h06, 8'h07, 8'h78};  
        end
        TX_SEND_MIX_DATA_2: begin
            txheader_in_A_r[1:0] <= 2'b10;
            gtwiz_userdata_tx_in_A_r[31:0] <= {8'h01, 8'h02, 8'h03, 8'h04};  
        end
        TX_SEND_DATA: begin
            txheader_in_A_r[1:0] <= 2'b10;
            gtwiz_userdata_tx_in_A_r[31:0] <= {8'h0c, 8'h0d, 8'h0e, 8'hff};  
        end
        TX_SEND_DATA_2: begin
            txheader_in_A_r[1:0] <= 2'b10;
            gtwiz_userdata_tx_in_A_r[31:0] <= {8'h08, 8'h09, 8'h0a, 8'h0b};  
        end
        endcase
    end

接收端同步检测模块

  同步检测算法与前文方式一致。

    always_comb begin
        case (rx_sync_fsm_A_r)
        RX_SYNC_RESET: begin
            if (gtwiz_reset_rx_done_out) begin
                rx_sync_fsm_A_s = RX_SYNC_OUT;
            end else begin
                rx_sync_fsm_A_s = RX_SYNC_RESET;
            end
        end
        RX_SYNC_OUT: begin 
            if (rxheadervalid_A_out & ^rxheader_A_out[1:0] && valid_sync_headers_cnt_A_r == 6'd63) begin
                rx_sync_fsm_A_s = RX_SYNC_IN;
            end else begin
                rx_sync_fsm_A_s = RX_SYNC_OUT;
            end
        end
        RX_SYNC_IN: begin
            if (rxheadervalid_A_out & ~(^rxheader_A_out[1:0]) && invalid_sync_headers_cnt_A_r == 5'd15) begin
                rx_sync_fsm_A_s = RX_SYNC_OUT;
            end else begin
                rx_sync_fsm_A_s = RX_SYNC_IN;
            end
        end
        default: rx_sync_fsm_A_s = RX_SYNC_RESET;
        endcase
    end

    always_ff @(posedge gtwiz_userclk_rx_usrclk2_out) begin
        case (rx_sync_fsm_A_s)
        RX_SYNC_RESET: begin
            rxgearboxslip_in <= 1'b0;
        end
        RX_SYNC_OUT: begin
            if (rxheadervalid_A_out && ~(^rxheader_A_out[1:0]) && headers_cnt_A_r == 6'd63) begin
                rxgearboxslip_in <= 1'b1;
            end else begin
                rxgearboxslip_in <= 1'b0;
            end
        end
        RX_SYNC_IN: begin
            rxgearboxslip_in <= 1'b0;
        end
        endcase
    end

接收模块

  通过将32bit数据移位合并为64bit数据进行识别处理,根据同步头有效与数据有效信号判断当前移位结果是否构成一个完整64bit数据。

    always_comb begin
        case (rx_fsm_A_r)
        RX_RESET: begin
            if (rx_reset_flag_A_rr) begin
                rx_fsm_A_s = RX_RESET;
            end else begin
                rx_fsm_A_s = RX_RECV;
            end
        end
        RX_RECV: begin 
            rx_fsm_A_s = RX_RECV;
        end
        default: rx_fsm_A_s = RX_RESET;
        endcase
    end
     
    always_ff @(posedge gtwiz_userclk_rx_usrclk2_out) begin
        case (rx_fsm_A_s)
        RX_RESET: begin
            rx_A_data <= 64'h0;
            rx_A_keep <= 8'h0;
            rx_A_strb <= 8'h0;
            rx_A_valid <= 1'b0;
            rx_A_last <= 1'b0;
        end
        RX_RECV: begin
            if (rxdatavalid_out_A_r) begin
                gtwiz_userdata_rx_out_A_r[31:0] <= gtwiz_userdata_rx_out_A_r[63:32];
            end

            if (~rxheadervalid_out_A_r & rxdatavalid_out_A_r) begin
                if (rxheader_out_A_d1_r[1:0] == 2'b10) begin
                    case (gtwiz_userdata_rx_out_A_r[7:0])
                    8'h78: begin            // S0D1D2D3/D4D5D6D7
                        rx_A_valid <= 1'b1;
                        rx_A_data <= {gtwiz_userdata_rx_out_A_r[63:8], 8'h0};
                        rx_A_keep <= 8'hff;
                        rx_A_strb <= 8'hfe;
                        rx_A_last <= 1'b0;
                    end
                    8'hff: begin            // D0D1D2D3/D4D5D6T7
                        rx_A_data <= {8'h0, gtwiz_userdata_rx_out_A_r[63:8]};
                        rx_A_keep <= 8'hff;
                        rx_A_strb <= 8'h7f;
                        rx_A_last <= 1'b1;
                    end
                    8'h1e: begin
                        rx_A_valid <= 1'b0;
                    end
                    endcase
                end else if (rxheader_out_A_d1_r[1:0] == 2'b01) begin
                    rx_A_data <= gtwiz_userdata_rx_out_A_r[63:0];
                    rx_A_keep <= 8'hff;
                    rx_A_strb <= 8'hff;
                    rx_A_last <= 1'b0;
                end
            end else begin
                rx_A_keep <= 8'h00;
                rx_A_strb <= 8'h00;
            end
        end
        endcase
    end

仿真测试

  仿真结果看到,在接收模块上,数据流A和B交叉输出,时分复用。

图片

上板测试

图片

完整代码

  完整代码可于同名公众号回复GTY_CAUI获取。


原文地址:https://blog.csdn.net/qq_45434284/article/details/137987857

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!