【问题标题】:Using CRC32 to validate the ethernet packet使用 CRC32 验证以太网数据包
【发布时间】:2016-10-19 00:06:43
【问题描述】:

我想计算以太网数据包的 crc32 并检查我是否收到了正确的数据。我想将 crc 实现为 System Verilog 函数。我将使用online crc value generator 获取verilog 中的代码来计算数据宽度为8 位的crc32。我有以下问题:

  1. 如果是以太网 802.3 标准,我相信 crc 是为数据计算的,其中数据 = {目标地址、源地址、长度和有效负载}。纠正我,如果我在数据中遗漏了什么。

  2. 理论上,数据附加了 (polynomial_length-1) 个零,在将数据消息作为输入发送到 crc32 函数之前,我是否必须进行类似的附加?

  3. 计算完 crc 后,现在我必须知道我收到的数据是否正确。那么,我是否必须再次将数据与计算出的 crc 值一起作为输入传递给 crc32 函数,以检查我是否得到零作为函数输出,以确保我收到正确的数据,这是正确的吗?如果没有告诉我如何检查我是否收到了正确的数据。提前致谢。

下面是我打算使用的crc32函数的SV版本。

function nextCRC32_D8(byte unsigned data[]);
 bit [7:0] d;
 bit [31:0] newcrc, crc,c;
 int i;
 crc=0;

for (i=0; i<data.size(); i++) begin
        d = data[i];
        c = crc;

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


end
return newcrc;
endfunction

【问题讨论】:

  • (3)的答案是肯定的。
  • @EJP (2) 怎么样?

标签: system-verilog ethernet crc crc32


【解决方案1】:
  1. 正确。
  2. CRC-32 算法,无论是软件还是硬件,都可以并且旨在避免在消息中附加零位的数学伪影。我尚未检查您发布的该属性的代码。
  3. 您完全按照传输时所做的操作,即通过有效负载计算地址上的 CRC(而 不是 CRC 本身),然后将其与传输数据包中的 CRC 进行比较.如果您愿意,您可以一直计算 CRC,并根据特定的“残差”值 0xC704DD7B 检查结果。那里发生的事情不太透明,但确实有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 2014-07-29
    • 2011-12-02
    • 2012-03-06
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    相关资源
    最近更新 更多