基于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)!