高速收发器: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问题的可能性很小。

 

 
复制代码

 

posted @   NoNounknow  阅读(100)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示