万兆以太网协议栈的FPGA实现(三):万兆网CRC

参考:

基于FPGA的千兆以太网的实现(3)_以太网crc计算-CSDN博客

https://www.bing.com/search?q=CRC+在线计算&cvid=2de0eff4c90a4d41b43981d4676f733f&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIGCAEQABhAMgYIAhAAGEAyBggDEAAYQDIGCAQQABhAMgYIBRAAGEAyBggGEAAYQDIGCAcQABhAMgYICBAAGEDSAQg0Mjg4ajBqNKgCCLACAQ&FORM=ANAB01&PC=HCTS

CRC 802.11来自将8位数据同时输入,再输出32位CRC数值;

其能成功实现的原因就是因为并行化。(下路仅是部分的计算步骤)

结合千兆网CRC的计算思想,我们只需要把第一轮单字节CRC的结果作为第二轮CRC的开始,就可以完成任务。

千兆网CRC:

  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

万兆网CRC

准备:

            reg   [31:00]   r_crc_value          ;//CRC 初始值
            reg   [07:00]   r_data       [07:00] ;//输入数据反转
            wire  [31:00]   w_crc_data   [07:00] ;//每8bit的计算结果
            reg   [31:00]   r_crc_media  [07:00] ;//传递r_crc_value和w_crc_data
            reg   [31:00]   r_crc_result [07:00] ;//CRC 输出

步骤1:初始化初始值,数值为上一次64bit计算的结果;

r_crc_value会每个时钟周期更新;
    always @(posedge i_clk) begin
        if(i_rst) begin
            r_crc_value <= 32'hffff_ffff;
        end else if(i_valid == 0) begin
            r_crc_value <= 32'hffff_ffff;
        end else if(i_valid == 1'b1) begin
            r_crc_value <= w_crc_data[7];
        end else begin
            r_crc_value <= r_crc_value;
        end
    end
 

步骤二:计算每个字节的CRC32:

        assign w_crc_data[i_1][0]  = r_crc_media[i_1][24] ^ r_crc_media[i_1][30] ^ r_i_data[i_1][0] ^ r_i_data[i_1][6];
        assign w_crc_data[i_1][1]  = r_crc_media[i_1][24] ^ r_crc_media[i_1][25] ^ r_crc_media[i_1][30]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][1] ^ r_i_data[i_1][6] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][2]  = r_crc_media[i_1][24] ^ r_crc_media[i_1][25] ^ r_crc_media[i_1][26]   ^ r_crc_media[i_1][30]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][1] ^ r_i_data[i_1][2] ^ r_i_data[i_1][6] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][3]  = r_crc_media[i_1][25] ^ r_crc_media[i_1][26] ^ r_crc_media[i_1][27]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][1] ^ r_i_data[i_1][2] ^ r_i_data[i_1][3] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][4]  = r_crc_media[i_1][24] ^ r_crc_media[i_1][26] ^ r_crc_media[i_1][27]   ^ r_crc_media[i_1][28]   ^ r_crc_media[i_1][30]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][2] ^ r_i_data[i_1][3] ^ r_i_data[i_1][4] ^ r_i_data[i_1][6];
        assign w_crc_data[i_1][5]  = r_crc_media[i_1][24] ^ r_crc_media[i_1][25] ^ r_crc_media[i_1][27]   ^ r_crc_media[i_1][28]   ^ r_crc_media[i_1][29]   ^ r_crc_media[i_1][30]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][1] ^ r_i_data[i_1][3] ^ r_i_data[i_1][4] ^ r_i_data[i_1][5] ^ r_i_data[i_1][6] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][6]  = r_crc_media[i_1][25] ^ r_crc_media[i_1][26] ^ r_crc_media[i_1][28]   ^ r_crc_media[i_1][29]   ^ r_crc_media[i_1][30]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][1] ^ r_i_data[i_1][2] ^ r_i_data[i_1][4] ^ r_i_data[i_1][5] ^ r_i_data[i_1][6] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][7]  = r_crc_media[i_1][24] ^ r_crc_media[i_1][26] ^ r_crc_media[i_1][27]   ^ r_crc_media[i_1][29]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][2] ^ r_i_data[i_1][3] ^ r_i_data[i_1][5] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][8]  = r_crc_media[i_1][0]  ^ r_crc_media[i_1][24] ^ r_crc_media[i_1][25]   ^ r_crc_media[i_1][27]   ^ r_crc_media[i_1][28]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][1] ^ r_i_data[i_1][3] ^ r_i_data[i_1][4];
        assign w_crc_data[i_1][9]  = r_crc_media[i_1][1]  ^ r_crc_media[i_1][25] ^ r_crc_media[i_1][26]   ^ r_crc_media[i_1][28]   ^ r_crc_media[i_1][29]   ^ r_i_data[i_1][1] ^ r_i_data[i_1][2] ^ r_i_data[i_1][4] ^ r_i_data[i_1][5];
        assign w_crc_data[i_1][10] = r_crc_media[i_1][2]  ^ r_crc_media[i_1][24] ^ r_crc_media[i_1][26]   ^ r_crc_media[i_1][27]   ^ r_crc_media[i_1][29]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][2] ^ r_i_data[i_1][3] ^ r_i_data[i_1][5];
        assign w_crc_data[i_1][11] = r_crc_media[i_1][3]  ^ r_crc_media[i_1][24] ^ r_crc_media[i_1][25]   ^ r_crc_media[i_1][27]   ^ r_crc_media[i_1][28]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][1] ^ r_i_data[i_1][3] ^ r_i_data[i_1][4];
        assign w_crc_data[i_1][12] = r_crc_media[i_1][4]  ^ r_crc_media[i_1][24] ^ r_crc_media[i_1][25]   ^ r_crc_media[i_1][26]   ^ r_crc_media[i_1][28]   ^ r_crc_media[i_1][29]   ^ r_crc_media[i_1][30]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][1] ^ r_i_data[i_1][2] ^ r_i_data[i_1][4] ^ r_i_data[i_1][5] ^ r_i_data[i_1][6];
        assign w_crc_data[i_1][13] = r_crc_media[i_1][5]  ^ r_crc_media[i_1][25] ^ r_crc_media[i_1][26]   ^ r_crc_media[i_1][27]   ^ r_crc_media[i_1][29]   ^ r_crc_media[i_1][30]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][1] ^ r_i_data[i_1][2] ^ r_i_data[i_1][3] ^ r_i_data[i_1][5] ^ r_i_data[i_1][6] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][14] = r_crc_media[i_1][6]  ^ r_crc_media[i_1][26] ^ r_crc_media[i_1][27]   ^ r_crc_media[i_1][28]   ^ r_crc_media[i_1][30]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][2] ^ r_i_data[i_1][3] ^ r_i_data[i_1][4] ^ r_i_data[i_1][6] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][15] = r_crc_media[i_1][7]  ^ r_crc_media[i_1][27] ^ r_crc_media[i_1][28]   ^ r_crc_media[i_1][29]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][3] ^ r_i_data[i_1][4] ^ r_i_data[i_1][5] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][16] = r_crc_media[i_1][8]  ^ r_crc_media[i_1][24] ^ r_crc_media[i_1][28]   ^ r_crc_media[i_1][29]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][4] ^ r_i_data[i_1][5];
        assign w_crc_data[i_1][17] = r_crc_media[i_1][9]  ^ r_crc_media[i_1][25] ^ r_crc_media[i_1][29]   ^ r_crc_media[i_1][30]   ^ r_i_data[i_1][1] ^ r_i_data[i_1][5] ^ r_i_data[i_1][6];
        assign w_crc_data[i_1][18] = r_crc_media[i_1][10] ^ r_crc_media[i_1][26] ^ r_crc_media[i_1][30]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][2] ^ r_i_data[i_1][6] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][19] = r_crc_media[i_1][11] ^ r_crc_media[i_1][27] ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][3] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][20] = r_crc_media[i_1][12] ^ r_crc_media[i_1][28] ^ r_i_data[i_1][4];
        assign w_crc_data[i_1][21] = r_crc_media[i_1][13] ^ r_crc_media[i_1][29] ^ r_i_data[i_1][5];
        assign w_crc_data[i_1][22] = r_crc_media[i_1][14] ^ r_crc_media[i_1][24] ^ r_i_data[i_1][0];
        assign w_crc_data[i_1][23] = r_crc_media[i_1][15] ^ r_crc_media[i_1][24] ^ r_crc_media[i_1][25]  ^ r_crc_media[i_1][30]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][1] ^ r_i_data[i_1][6];
        assign w_crc_data[i_1][24] = r_crc_media[i_1][16] ^ r_crc_media[i_1][25] ^ r_crc_media[i_1][26]  ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][1] ^ r_i_data[i_1][2] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][25] = r_crc_media[i_1][17] ^ r_crc_media[i_1][26] ^ r_crc_media[i_1][27]  ^ r_i_data[i_1][2] ^ r_i_data[i_1][3];
        assign w_crc_data[i_1][26] = r_crc_media[i_1][18] ^ r_crc_media[i_1][24] ^ r_crc_media[i_1][27]  ^ r_crc_media[i_1][28]   ^ r_crc_media[i_1][30]   ^ r_i_data[i_1][0] ^ r_i_data[i_1][3] ^ r_i_data[i_1][4] ^ r_i_data[i_1][6];
        assign w_crc_data[i_1][27] = r_crc_media[i_1][19] ^ r_crc_media[i_1][25] ^ r_crc_media[i_1][28]  ^ r_crc_media[i_1][29]   ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][1] ^ r_i_data[i_1][4] ^ r_i_data[i_1][5] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][28] = r_crc_media[i_1][20] ^ r_crc_media[i_1][26] ^ r_crc_media[i_1][29]  ^ r_crc_media[i_1][30]   ^ r_i_data[i_1][2] ^ r_i_data[i_1][5] ^ r_i_data[i_1][6];
        assign w_crc_data[i_1][29] = r_crc_media[i_1][21] ^ r_crc_media[i_1][27] ^ r_crc_media[i_1][30]  ^ r_crc_media[i_1][31]   ^ r_i_data[i_1][3] ^ r_i_data[i_1][6] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][30] = r_crc_media[i_1][22] ^ r_crc_media[i_1][28] ^ r_crc_media[i_1][31]  ^ r_i_data[i_1][4] ^ r_i_data[i_1][7];
        assign w_crc_data[i_1][31] = r_crc_media[i_1][23] ^ r_crc_media[i_1][29] ^ r_i_data[i_1][5];

步骤三:将每个字节的CRC结果作为下一个字节CRC的初始值:

r_crc_media用来记录这个数值;
r_crc_media[0]是上一轮计算的结果;作为这一轮CRC的初值;
如果是第一个字节,上一个字节就是上一轮的结果;
        always @(*) begin
            if(i_1 > 0) begin
                r_crc_media[i_1] = w_crc_data[i_1-1];
            end else begin
                r_crc_media[i_1] = r_crc_media[i_1];
            end
        end

循环步骤2-3 8次。

即可完成计算。

 

posted @ 2024-08-19 22:36  NoNounknow  阅读(18)  评论(0编辑  收藏  举报