高速收发器:PHY层笔记(一)
笔记:
高速收发器的数据位宽通常有:2,4,8字节等;
PCIE喜欢的位宽是1DW = 4 Byte;
这里对高速收发器的设计为4 Byte也就是32位宽;
GT中PHY层的字对齐和掩码处理
高速收发器的数据流以SOT开始(和MIPI一样),GT的SOT一般就是K码,标志了开始,其也具有EOT,标志了结束;
但与MIPI有很大的不同,GT的K码可能会出现在数据端口的某一个字节上,接收端接收的顺序次序是随机的;
以32位宽违例:
{D0,D1,D2,D3} , SOT可能会出现在任何一个D的位置上;(EOT也需要处理这种情况)
我设置的是32/40的any边界,所以在四个字节的位置上出现都是有可能的。
这就意味着类似于MIPI的字对齐操作需要时刻进行;
//Search_Byte_Offset reg [3:0] i; always @(posedge I_CLK or negedge I_Rst_n) begin if(I_Rst_n == 1'b0) begin Byte_Offset <= 4'b0; Search_Locking <= 1'b0; end else if(!ReSearch_delay && I_ReSearch_Offset) begin Byte_Offset <= 4'b0; Search_Locking <= 1'b0; end else if(Search_Locking == 1'b0) begin for(i=8'h0;i<8;i=i+1) begin if(Concat_Byte_data[(i+1'b1)+:8] == SoT) begin Byte_Offset <= i[2:0] + 1'b1; Search_Locking <= 1'b1; end end end end
同时这还涉及掩码信号,其实就是AXI协议中的字节有效(PCIE中也有这种操作);
1.字对齐;
2.掩码处理;
我尝试用FOR来写,不好用;这个是错的,只是分享一下;
for(r_looking_i=8'h0;r_looking_i < 32;r_looking_i = r_looking_i + 8) begin if(r_i_gt_rx_data[r_looking_i+:15] == P_Sync_Code[15:00]) begin if(r_looking_i == 0 && r_i_gt_rx_data[16+:8] == P_SoT_Code[07:00]) begin r_commoa_access == 1'b1; end else if(r_looking_i == 0 && r_i_gt_rx_data[24+:8] == P_SoT_Code[07:00]) begin r_commoa_access == 1'b1; end else if(r_looking_i == 8 && r_i_gt_rx_data[24+:8] == P_SoT_Code[07:00]) begin r_commoa_access == 1'b1; end else if(r_looking_i == 8 && i_gt_rx_data[07:00] == P_SoT_Code[07:00]) begin r_commoa_access == 1'b1; end else if(r_looking_i == 16 && r_i_gt_rx_data[24+:8] == P_SoT_Code[07:00]) begin r_commoa_access == 1'b1; end end end
这是我的现在写法:
always @(posedge i_sys_clk) begin if(i_sys_rst == 1'b1) begin r_o_axi_s_keep <= 4'b0000; end else if((r_sof_check == 1'b1)||(r_data_process == 1'b1)) begin if(r_sof_mark == 4'b0001) begin if(r_eof_mark == 4'b0001 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1110; end else if(r_eof_mark == 4'b0010 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1111; end else if(r_eof_mark == 4'b0100 && r_d1_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1000; end else if(r_eof_mark == 4'b1000 && r_d1_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1100; end else begin r_o_axi_s_keep <= 4'b1111; end end else if(r_sof_mark == 4'b0010) begin if(r_eof_mark == 4'b0001 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1100; end else if(r_eof_mark == 4'b0010 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1110; end else if(r_eof_mark == 4'b0100 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1111; end else if(r_eof_mark == 4'b1000 && r_d1_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1000; end else begin r_o_axi_s_keep <= 4'b1111; end end else if(r_sof_mark == 4'b0100) begin if(r_eof_mark == 4'b0001 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1000; end else if(r_eof_mark == 4'b0010 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1100; end else if(r_eof_mark == 4'b0100 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1110; end else if(r_eof_mark == 4'b1000 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1111; end else begin r_o_axi_s_keep <= 4'b1111; end end else if(r_sof_mark == 4'b1000) begin if(r_eof_mark == 4'b0001 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b0000; end else if(r_eof_mark == 4'b0010 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1000; end else if(r_eof_mark == 4'b0100 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1100; end else if(r_eof_mark == 4'b1000 && r_eof_check == 1'b1) begin r_o_axi_s_keep <= 4'b1110; end else begin r_o_axi_s_keep <= 4'b1111; end end end else begin r_o_axi_s_keep <= 4'b0000; end end
GT PHY到万兆网:万兆网MAC层的CRC处理
千兆网的CRC是8d32的:http://outputlogic.com/?page_id=321
但是如果选取了万兆网的32用户位宽,需要使用32d32,并且带掩码的CRC运算;
例如:
1.传输五个字节D0-D4;
2.D0-D3输入CRC模块进行校验;
3.D4就不能直接输入计算了,需要结合掩码完成;
发送数据所需要的数据流组成
同步码+SOT+DATA+EOF+LFSR
K28,5:1011 1100 (BC)
SOT:K27.7:8b/10B编码规定;111 11011(FB)
EOF:K29.7:111 11101(FD)
空闲:K23.7:111 10111(F7)并不用得到这个,而是直接使用LFSR;
同步码:一般需要多组同步码,才能保障稳定;
EMI问题:处于空闲状态的时候,如果一直在发送数值,会引起严重的尖峰问题,从而带来巨大的电磁辐射;
所以在空闲的时候,需要发送LFSP(伪随机码)序列,这是一种频谱近似于白噪声的序列,所以辐射较小,产生EMI问题的可能性很小。