高速收发器:PHY层代码(二)

TX:

总结:不难,只需要注意小端发送即可;

我选取的实现思路是使用VAILD信号计数,延迟几个周期之后启动发送计数器,发送计算器在其计数数值来到VAILD信号计数器的最大值-1后结束;

思路很简单,事实上这就是一个很常见的组帧模块,和其他的没有什么本质的差别;

    always @(posedge i_sys_clk) begin
        if(i_sys_rst == 1'b1) begin
            r_o_gt_tx_data <=  w_lfsr_data;
            r_o_gt_tx_char <=  4'b0000;
        end else if(r_st_current == P_ST_ICOMMOA) begin
            r_o_gt_tx_data <= {P_Sync_Code[07-:8],P_Sync_Code[15-:8],P_Sync_Code[23-:8],P_Sync_Code[31-:8]};
            r_o_gt_tx_char <= 4'b0101;
        end else if(r_st_current == P_ST_COMMOA) begin
            r_o_gt_tx_data <= {P_Sync_Code[07-:8],P_Sync_Code[15-:8],P_Sync_Code[23-:8],P_Sync_Code[31-:8]};
            r_o_gt_tx_char <= 4'b0101;
        end else if(r_st_current == P_ST_SOF) begin
            r_o_gt_tx_data <= {w_Gt_tx_fifo_dout[15-:8],w_Gt_tx_fifo_dout[23-:8],w_Gt_tx_fifo_dout[31-:8],P_SoT_Code[07-:8]};
            r_o_gt_tx_char <= 4'b0001;
        end else if(r_st_current == P_ST_DATA) begin
            r_o_gt_tx_data <= {w_Gt_tx_fifo_dout[15-:8],w_Gt_tx_fifo_dout[23-:8],w_Gt_tx_fifo_dout[31-:8],r_Gt_tx_fifo_dout[07-:8]};
            r_o_gt_tx_char <= 4'b0000;
        end else if(r_st_current == P_ST_EOF1) begin
            if(r_i_axi_s_keep == 4'b1000) begin
                r_o_gt_tx_data <= {w_lfsr_data[07:00],P_EoT_Code[07:00],w_Gt_tx_fifo_dout[31-:8],r_Gt_tx_fifo_dout[07-:8]};
                r_o_gt_tx_char <= 4'b0100;
            end else if(r_i_axi_s_keep == 4'b1100) begin
                r_o_gt_tx_data <= {P_EoT_Code[07:00],w_Gt_tx_fifo_dout[23-:8],w_Gt_tx_fifo_dout[31-:8],r_Gt_tx_fifo_dout[07-:8]};
                r_o_gt_tx_char <= 4'b1000;
            end else if(r_i_axi_s_keep == 4'b1110) begin
                r_o_gt_tx_data <= {w_Gt_tx_fifo_dout[15-:8],w_Gt_tx_fifo_dout[23-:8],w_Gt_tx_fifo_dout[31-:8],r_Gt_tx_fifo_dout[07-:8]};
                r_o_gt_tx_char <= 4'b0000;
            end else if(r_i_axi_s_keep == 4'b1111) begin
                r_o_gt_tx_data <= {w_Gt_tx_fifo_dout[15-:8],w_Gt_tx_fifo_dout[23-:8],w_Gt_tx_fifo_dout[31-:8],r_Gt_tx_fifo_dout[07-:8]};
                r_o_gt_tx_char <= 4'b0000;
            end else begin
                r_o_gt_tx_data <= 32'h0000;
                r_o_gt_tx_char <=  4'b0000;
            end
        end else if(r_st_current == P_ST_EOF2) begin
            if(r_i_axi_s_keep == 4'b1110) begin
                r_o_gt_tx_data <= {w_lfsr_data[23-:24],P_EoT_Code[07:00]};
                r_o_gt_tx_char <=  4'b0001;
            end else if(r_i_axi_s_keep == 4'b1111) begin
                r_o_gt_tx_data <= {w_lfsr_data[15-:16],P_EoT_Code[07:00],r_Gt_tx_fifo_dout[07-:8]};
                r_o_gt_tx_char <=  4'b0010;
            end else begin
                r_o_gt_tx_data <=  w_lfsr_data;
                r_o_gt_tx_char <=  4'b0000;
            end
        end else begin
            r_o_gt_tx_data <=  w_lfsr_data;
            r_o_gt_tx_char <=  4'b0000;
        end
    end

 

RX:

总结:默认小端存储需要转大端,对齐很麻烦,准确的筛选所需的字节也很麻烦;

推荐画图来理解;

我个人的总结规律是:

0.SOF的标志作为VAILD的起始信号;

1.SOF和EOF处字节相加大于用户数据位宽的时候,需要将EOF的标志延迟两拍作为VAILD的结束信号;

2.SOF和EOF处字节小于等于用户数据位宽的时候,需要将EOF的标志延迟一拍作为VAILD的结束信号;

3.如果相加为零,则选择EOF的标志作为VAILD的结束信号;

当然,这只是一个思路,这个延迟是相对来说的,如果你用其他方式来判断SOF或者EOF,只需要按我这个相对的概念修改即可;

    always @(posedge i_sys_clk) begin
        if(i_sys_rst == 1'b1) begin
            r_o_axi_s_vaild <= 1'b0;
        end else if((r_sof_mark == 4'b0001) && (r_eof_mark == 4'b0001 || r_eof_mark == 4'b0010) && (r_d1_eof_check == 1'b1)) begin
            r_o_axi_s_vaild <= 1'b0;
        end else if((r_sof_mark == 4'b0001) && (r_eof_mark == 4'b0100 || r_eof_mark == 4'b1000) && (r_d2_eof_check == 1'b1)) begin
            r_o_axi_s_vaild <= 1'b0;
        end else if((r_sof_mark == 4'b0010) && (r_eof_mark == 4'b0001 || r_eof_mark == 4'b0010 || r_eof_mark == 4'b0100) && (r_d1_eof_check == 1'b1)) begin
            r_o_axi_s_vaild <= 1'b0;
        end else if((r_sof_mark == 4'b0010) && (r_eof_mark == 4'b1000) && (r_d2_eof_check == 1'b1)) begin
            r_o_axi_s_vaild <= 1'b0;
        end else if((r_sof_mark == 4'b0100) && (r_d1_eof_check == 1'b1)) begin
            r_o_axi_s_vaild <= 1'b0;
        end else if((r_sof_mark == 4'b1000) && (r_eof_mark == 4'b0001) && (r_eof_check == 1'b1)) begin
            r_o_axi_s_vaild <= 1'b0;
        end else if((r_sof_mark == 4'b1000) && (r_eof_mark == 4'b0010 || r_eof_mark == 4'b0100 || r_eof_mark == 4'b1000) && (r_d1_eof_check == 1'b1)) begin
            r_o_axi_s_vaild <= 1'b0;
        end else if(r_sof_check == 1'b1) begin
            r_o_axi_s_vaild <= 1'b1;
        end
    end

    always @(*) begin
        if((r_sof_mark == 4'b0001) && (r_eof_mark == 4'b0001 || r_eof_mark == 4'b0010) && (r_d1_eof_check == 1'b1)) begin
            r_o_axi_s_last <= 1'b1;
        end else if((r_sof_mark == 4'b0001) && (r_eof_mark == 4'b0100 || r_eof_mark == 4'b1000) && (r_d2_eof_check == 1'b1)) begin
            r_o_axi_s_last <= 1'b1;
        end else if((r_sof_mark == 4'b0010) && (r_eof_mark == 4'b0001 || r_eof_mark == 4'b0010 || r_eof_mark == 4'b0100) && (r_d1_eof_check == 1'b1)) begin
            r_o_axi_s_last <= 1'b1;
        end else if((r_sof_mark == 4'b0010) && (r_eof_mark == 4'b1000) && (r_d2_eof_check == 1'b1)) begin
            r_o_axi_s_last <= 1'b1;
        end else if((r_sof_mark == 4'b0100) && (r_d1_eof_check == 1'b1)) begin
            r_o_axi_s_last <= 1'b1;
        end else if((r_sof_mark == 4'b1000) && (r_eof_mark == 4'b0001) && (r_eof_check == 1'b1)) begin
            r_o_axi_s_last <= 1'b1;
        end else if((r_sof_mark == 4'b1000) && (r_eof_mark == 4'b0010 || r_eof_mark == 4'b0100 || r_eof_mark == 4'b1000) && (r_d1_eof_check == 1'b1)) begin
            r_o_axi_s_last <= 1'b1;
        end else begin
            r_o_axi_s_last <= 0;
        end
    end

    always @(posedge i_sys_clk) begin
        if(i_sys_rst == 1'b1) begin
            r_o_axi_s_data <= 32'h0000;
        end else if((r_sof_check == 1'b1)||(r_data_process == 1'b1)) begin
            if(r_sof_mark == 4'b0001) begin
                r_o_axi_s_data <= {r_2d_i_gt_rx_data[07-:08],r_3d_i_gt_rx_data[31-:24]};
            end else if(r_sof_mark == 4'b0010) begin
                r_o_axi_s_data <= {r_2d_i_gt_rx_data[15-:16],r_3d_i_gt_rx_data[31-:16]};
            end else if(r_sof_mark == 4'b0100) begin
                r_o_axi_s_data <= {r_2d_i_gt_rx_data[23-:24],r_3d_i_gt_rx_data[31-:08]};
            end else if(r_sof_mark == 4'b1000) begin
                r_o_axi_s_data <= {r_2d_i_gt_rx_data[31-:32]};
            end else begin
                r_o_axi_s_data <= 32'h0000;
            end
        end else begin
            r_o_axi_s_data <= 32'h0000;
        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

 

posted @ 2024-07-29 21:23  NoNounknow  阅读(32)  评论(0编辑  收藏  举报