【CRC校验方法】+【FPGA实现(发送端)】

书接上回:

https://www.cnblogs.com/VerweileDoch/p/18105959

发送端的逻辑和接收端类似,但是需要进行八位内的逆运算和取反:

    always @(posedge sys_clk) begin
        if(sys_rst_n == 1'b0) begin
            r1_crc_value <= 32'h0;
        end else if(crc_cycle == 1'b1 && crc_cnt == 'd3) begin
            r1_crc_value <= 32'h0;
        end else if(i_vaild == 1'b0 && r1_i_vaild == 1'b1) begin
            r1_crc_value <= crc_value;
        end
    end

    reg [7:0] inver_i;
    always @(*) begin
        for (inver_i = 0;inver_i < 8;inver_i = inver_i + 1'b1 ) begin
            r2_crc_value[31 - inver_i] <= r1_crc_value[24 + inver_i];
            r2_crc_value[23 - inver_i] <= r1_crc_value[16 + inver_i];
            r2_crc_value[15 - inver_i] <= r1_crc_value[08 + inver_i];
            r2_crc_value[07 - inver_i] <= r1_crc_value[0  + inver_i];
        end
    end 

    always @(posedge sys_clk) begin
        if(sys_rst_n == 1'b0) begin
            r_o_data <= 8'hff;
        end else if(r1_i_vaild == 1'b1 && crc_cycle == 1'b0) begin
            r_o_data <= r1_i_data;
        end else if(crc_cycle == 1'b1) begin
            r_o_data <= ~(r2_crc_value[(31-(crc_cnt << 3))-:8]);
        end else begin
            r_o_data <= 8'hff;
        end
    end

完整代码:

module CRC_buffer #(
    parameter   UDP_CODE             =  8'h11                                           ,
    parameter   TX_TARGET_PORT       = 16'd808                                          ,
    parameter   TX_SOURCE_PORT       = 16'd8080                                         ,
    parameter   RX_Sync_Frame        = 32'hF05AA50F                                     ,
    parameter   TX_SOURCE_Addr       = {8'd192,8'd168,8'd0,8'd1}                        ,
    parameter   TX_TARGET_Addr       = {8'hFF,8'hFF,8'hFF,8'hFF}                        ,
    //Length
    parameter   TX_PREAMBLE          = {8'h55,8'h55,8'h55,8'h55,8'h55,8'h55,8'h55,8'hD5},
    parameter   TX_TARGET_MAC        = {8'hFF,8'hFF,8'hFF,8'hFF,8'hFF,8'hFF}            ,// broadcast packet
    parameter   TX_SOURECE_MAC       = {8'hA8,8'hB2,8'h3C,8'h7D,8'h97,8'hD7}            , 
    parameter   Length_HeartBeat     = 16'd92                                           ,
    parameter   Length_UDP           = 16'd72                                           ,
    parameter   Length_HeartBeat_all = 8'd114                                           ,
    parameter   Length_EnCODE_Packet = 8'd114 
)(
    input   wire            sys_clk            ,
    input   wire            sys_rst_n          ,
    input   wire            i_vaild            ,
    input   wire  [7:0]     i_data             ,
    output  wire            o_vaild            ,
    output  wire  [7:0]     o_data                   
);
            wire  [31:00]   crc_value          ;
             reg  [31:00]   r1_crc_value       ;
             reg  [31:00]   r2_crc_value       ;

            reg             r1_i_vaild         ;  
            reg             r2_i_vaild         ;
            reg   [7:0]     r1_i_data          ;              
            reg   [15:00]   i_vaild_cnt        ;

            reg             crc_cycle          ;
            reg             r_crc_cycle        ;
            reg   [03:00]   crc_cnt            ;

            reg   [07:00]   r_o_data           ;

    always @(posedge sys_clk) begin
        if(sys_rst_n == 1'b0) begin
            i_vaild_cnt <= 16'd0;
        end else if(i_vaild == 1'b1) begin
            if(i_vaild_cnt == Length_EnCODE_Packet - 1'b1) begin
                i_vaild_cnt <= 16'd0;
            end else begin
                i_vaild_cnt <= i_vaild_cnt + 1'b1;
            end
        end
    end

    always @(posedge sys_clk) begin
        r1_i_vaild  <= i_vaild;  
        r2_i_vaild  <= r1_i_vaild;
        r1_i_data   <= i_data ; 
        r_crc_cycle <=  crc_cycle;
    end

    always @(posedge sys_clk) begin
        if(sys_rst_n == 1'b0) begin
            r1_crc_value <= 32'h0;
        end else if(crc_cycle == 1'b1 && crc_cnt == 'd3) begin
            r1_crc_value <= 32'h0;
        end else if(i_vaild == 1'b0 && r1_i_vaild == 1'b1) begin
            r1_crc_value <= crc_value;
        end
    end

    reg [7:0] inver_i;
    always @(*) begin
        for (inver_i = 0;inver_i < 8;inver_i = inver_i + 1'b1 ) begin
            r2_crc_value[31 - inver_i] <= r1_crc_value[24 + inver_i];
            r2_crc_value[23 - inver_i] <= r1_crc_value[16 + inver_i];
            r2_crc_value[15 - inver_i] <= r1_crc_value[08 + inver_i];
            r2_crc_value[07 - inver_i] <= r1_crc_value[0  + inver_i];
        end
    end 

    always @(posedge sys_clk) begin
        if(sys_rst_n == 1'b0) begin
            crc_cycle <= 1'b0;
        end else if(crc_cycle == 1'b1 && crc_cnt == 'd3) begin
            crc_cycle <= 1'b0;
        end else if(i_vaild == 1'b0 && r1_i_vaild == 1'b1) begin
            crc_cycle <= 1'b1;
        end else begin
            crc_cycle <= crc_cycle;
        end
    end

    always @(posedge sys_clk) begin
        if(sys_rst_n == 1'b0) begin
            crc_cnt <= 4'h0;
        end else if(crc_cycle == 1'b1) begin
            if(crc_cnt== 'd3) begin
                crc_cnt <= 4'h0;
            end else begin
                crc_cnt <= crc_cnt + 1'b1;
            end
        end else begin
            crc_cnt <= 4'h0;
        end
    end 

    always @(posedge sys_clk) begin
        if(sys_rst_n == 1'b0) begin
            r_o_data <= 8'hff;
        end else if(r1_i_vaild == 1'b1 && crc_cycle == 1'b0) begin
            r_o_data <= r1_i_data;
        end else if(crc_cycle == 1'b1) begin
            r_o_data <= ~(r2_crc_value[(31-(crc_cnt << 3))-:8]);
        end else begin
            r_o_data <= 8'hff;
        end
    end

    assign  o_vaild = (r2_i_vaild)||(r_crc_cycle);
    assign  o_data = r_o_data;

CRC32_D8_Out  CRC32_D8_Out_inst0 (
    .i_clk                   ( sys_clk       ),
    .i_rst_n                 ( sys_rst_n     ),
    .i_data                  ( i_data        ),
    .i_vaild                 ( i_vaild       ),

    .o_crc_error             (               ),
    .o_crc_end               (               ),
    .o_crc_value             ( crc_value     )
);
    reg [07:00] test_cnt;
    always @(posedge sys_clk) begin
        if(sys_rst_n == 1'b0) begin
            test_cnt <= 8'd0;
        end else if(o_vaild == 1'b1) begin
            test_cnt <= test_cnt + 1'b1;
        end else begin
            test_cnt <= 8'd0;
        end
    end 
endmodule

 

module CRC32_D8_Out (
    input   wire            i_clk       ,
    input   wire            i_rst_n     ,
    input   wire  [7:0]     i_data      ,
    input   wire            i_vaild     ,
    output  wire            o_crc_error ,
    output  wire            o_crc_end   ,
    output  wire  [31:0]    o_crc_value
);
             reg            r_i_vaild       ;
             reg  [7:0]     r_i_data        ;          
             reg  [31:0]    crc_r           ;
             reg  [31:0]    crc_lfsr        ;
             reg            r_crc32_error   ;
             reg  [15:0]    vaild_cnt       ;
             reg            filter_vaild    ;
             wire           crc_end         ;
             reg            r_crc_end       ;

///////////////////////////////////////////////////////////////////////////
    assign crc_end = (i_vaild == 1'b0 && r_i_vaild == 1'b1);
    assign o_crc_error = r_crc32_error;
    assign o_crc_end   = r_crc_end    ;
    assign o_crc_value = crc_r        ;

    always @(posedge i_clk) begin
        if (i_rst_n==0) begin
            vaild_cnt <= 'd0;
        end else if(i_vaild == 1'b0 && r_i_vaild == 1'b1) begin
            vaild_cnt <= 'd0;
        end else if(i_vaild == 1'b1) begin
            vaild_cnt <= vaild_cnt + 1'b1;
        end else begin
            vaild_cnt <= vaild_cnt;
        end
    end

    always @(*) begin
        if(vaild_cnt >= 4'd8 && i_vaild == 1'b1) begin
            filter_vaild <= 1'b1;
        end else begin
            filter_vaild <= 1'b0;
        end
    end

    always @(posedge i_clk) begin
        r_i_vaild   <= i_vaild;
        r_crc_end   <= crc_end;
    end

    always@(posedge i_clk) begin
        if (i_rst_n==0) begin
            r_crc32_error <= 1'b0;
        end else if (i_vaild == 1'b0 && r_i_vaild == 1'b1) begin
            if (crc_r==32'hc704dd7b) begin
                r_crc32_error <= 1'b0;
            end else begin
                r_crc32_error <= 1'b1;
            end
        end else begin
            r_crc32_error <= 1'b0;
        end
    end

    always @(posedge i_clk) begin
        if(i_rst_n == 1'b0) begin
            crc_r <= 32'hffff_ffff;
        end else if(filter_vaild == 1'b1) begin
            crc_r <= crc_lfsr;
        end else if(i_vaild == 1'b0 && r_i_vaild == 1'b1)begin
            crc_r <= 32'hffff_ffff;
        end else begin
            crc_r <= crc_r;
        end
    end

    reg [3:0] data_inver_i;
    always @(*) begin
        for(data_inver_i = 0;data_inver_i < 8;data_inver_i = data_inver_i + 1) begin
            r_i_data[data_inver_i] <= i_data[7-data_inver_i];
        end
    end

  always @(*) begin
        crc_lfsr[0]  = crc_r[24] ^ crc_r[30] ^ r_i_data[0] ^ r_i_data[6];
        crc_lfsr[1]  = crc_r[24] ^ crc_r[25] ^ crc_r[30]   ^ crc_r[31]   ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[6] ^ r_i_data[7];
        crc_lfsr[2]  = crc_r[24] ^ crc_r[25] ^ crc_r[26]   ^ crc_r[30]   ^ crc_r[31]   ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[6] ^ r_i_data[7];
        crc_lfsr[3]  = crc_r[25] ^ crc_r[26] ^ crc_r[27]   ^ crc_r[31]   ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[7];
        crc_lfsr[4]  = crc_r[24] ^ crc_r[26] ^ crc_r[27]   ^ crc_r[28]   ^ crc_r[30]   ^ r_i_data[0] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[6];
        crc_lfsr[5]  = crc_r[24] ^ crc_r[25] ^ crc_r[27]   ^ crc_r[28]   ^ crc_r[29]   ^ crc_r[30]   ^ crc_r[31]   ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[6] ^ r_i_data[7];
        crc_lfsr[6]  = crc_r[25] ^ crc_r[26] ^ crc_r[28]   ^ crc_r[29]   ^ crc_r[30]   ^ crc_r[31]   ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[6] ^ r_i_data[7];
        crc_lfsr[7]  = crc_r[24] ^ crc_r[26] ^ crc_r[27]   ^ crc_r[29]   ^ crc_r[31]   ^ r_i_data[0] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[5] ^ r_i_data[7];
        crc_lfsr[8]  = crc_r[0]  ^ crc_r[24] ^ crc_r[25]   ^ crc_r[27]   ^ crc_r[28]   ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[3] ^ r_i_data[4];
        crc_lfsr[9]  = crc_r[1]  ^ crc_r[25] ^ crc_r[26]   ^ crc_r[28]   ^ crc_r[29]   ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[4] ^ r_i_data[5];
        crc_lfsr[10] = crc_r[2]  ^ crc_r[24] ^ crc_r[26]   ^ crc_r[27]   ^ crc_r[29]   ^ r_i_data[0] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[5];
        crc_lfsr[11] = crc_r[3]  ^ crc_r[24] ^ crc_r[25]   ^ crc_r[27]   ^ crc_r[28]   ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[3] ^ r_i_data[4];
        crc_lfsr[12] = crc_r[4]  ^ crc_r[24] ^ crc_r[25]   ^ crc_r[26]   ^ crc_r[28]   ^ crc_r[29]   ^ crc_r[30]   ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[6];
        crc_lfsr[13] = crc_r[5]  ^ crc_r[25] ^ crc_r[26]   ^ crc_r[27]   ^ crc_r[29]   ^ crc_r[30]   ^ crc_r[31]   ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[5] ^ r_i_data[6] ^ r_i_data[7];
        crc_lfsr[14] = crc_r[6]  ^ crc_r[26] ^ crc_r[27]   ^ crc_r[28]   ^ crc_r[30]   ^ crc_r[31]   ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[6] ^ r_i_data[7];
        crc_lfsr[15] = crc_r[7]  ^ crc_r[27] ^ crc_r[28]   ^ crc_r[29]   ^ crc_r[31]   ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[7];
        crc_lfsr[16] = crc_r[8]  ^ crc_r[24] ^ crc_r[28]   ^ crc_r[29]   ^ r_i_data[0] ^ r_i_data[4] ^ r_i_data[5];
        crc_lfsr[17] = crc_r[9]  ^ crc_r[25] ^ crc_r[29]   ^ crc_r[30]   ^ r_i_data[1] ^ r_i_data[5] ^ r_i_data[6];
        crc_lfsr[18] = crc_r[10] ^ crc_r[26] ^ crc_r[30]   ^ crc_r[31]   ^ r_i_data[2] ^ r_i_data[6] ^ r_i_data[7];
        crc_lfsr[19] = crc_r[11] ^ crc_r[27] ^ crc_r[31]   ^ r_i_data[3] ^ r_i_data[7];
        crc_lfsr[20] = crc_r[12] ^ crc_r[28] ^ r_i_data[4];
        crc_lfsr[21] = crc_r[13] ^ crc_r[29] ^ r_i_data[5];
        crc_lfsr[22] = crc_r[14] ^ crc_r[24] ^ r_i_data[0];
        crc_lfsr[23] = crc_r[15] ^ crc_r[24] ^ crc_r[25]  ^ crc_r[30]   ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[6];
        crc_lfsr[24] = crc_r[16] ^ crc_r[25] ^ crc_r[26]  ^ crc_r[31]   ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[7];
        crc_lfsr[25] = crc_r[17] ^ crc_r[26] ^ crc_r[27]  ^ r_i_data[2] ^ r_i_data[3];
        crc_lfsr[26] = crc_r[18] ^ crc_r[24] ^ crc_r[27]  ^ crc_r[28]   ^ crc_r[30]   ^ r_i_data[0] ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[6];
        crc_lfsr[27] = crc_r[19] ^ crc_r[25] ^ crc_r[28]  ^ crc_r[29]   ^ crc_r[31]   ^ r_i_data[1] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[7];
        crc_lfsr[28] = crc_r[20] ^ crc_r[26] ^ crc_r[29]  ^ crc_r[30]   ^ r_i_data[2] ^ r_i_data[5] ^ r_i_data[6];
        crc_lfsr[29] = crc_r[21] ^ crc_r[27] ^ crc_r[30]  ^ crc_r[31]   ^ r_i_data[3] ^ r_i_data[6] ^ r_i_data[7];
        crc_lfsr[30] = crc_r[22] ^ crc_r[28] ^ crc_r[31]  ^ r_i_data[4] ^ r_i_data[7];
        crc_lfsr[31] = crc_r[23] ^ crc_r[29] ^ r_i_data[5];
    end // always
///////////////////////////////////////////////////////////////////////////
endmodule

 

posted @ 2024-04-09 21:17  NoNounknow  阅读(199)  评论(0)    收藏  举报