【问题标题】:how to calculate CRC32 for 5-bit valid data using 8-bit parallel CRC calculator?如何使用 8 位并行 CRC 计算器计算 5 位有效数据的 CRC32?
【发布时间】:2016-11-28 09:09:14
【问题描述】:

我有一个 VHDL 中可用的 8 位并行 CRC32 计算器逻辑。我只想通过 5 个有效数据位 计算 CRC-32。我该怎么做?

假设“my_data”是:“01010” 但问题是我的 CRC 计算器需要 8 位数据,所以我尝试在“my_data”末尾附加 3-0,所以它看起来像这样:“01010_000”。通过这样做,我得到了错误的 CRC32 结果。

【问题讨论】:

  • 如果将零添加到数据的另一端会怎样?
  • 所以我尝试在“my_data”的末尾附加 3-0,所以它看起来像这样:“01010_000”。通过这样做,我得到了错误的 CRC32 结果。
  • 是的,所以试着把零放在另一端
  • 查找或生成一个 5 位并行 CRC32 '计算器'。
  • @scary_jeff 还是没用。

标签: vhdl crc32


【解决方案1】:

将您的 5 位放在您将提供给逻辑的 8 位中的最高有效位中,使最低有效三位全为零。异或与0x996495a3 的结果。完成。

您需要将五个位放在字节的最高有效位中,因为您的 CRC 从最低有效位开始。在您的五个位之前提供一组常量位只会将结果更改为具有某个常量的异或。 (我们可以将低三位设置为任何内容,只要它们始终相同。那么只有我们排斥的常数或结果会改变。)

您可以通过将五个零位的 CRC 与八个零位的 CRC 异或来获得0x996495a3

此 C 例程计算任意数量的零位的标准 CRC-32(您正在使用的,最终异或全为 1):

uint32_t crc32zeros(unsigned zeros) {
    uint32_t crc = ~0;
    while (zeros--)
        crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
    return ~crc;
}

然后:

crc32zeros(5) ^ crc32zeros(8) == 0x996495a3

最后的反转不会改变你得到的常数,因为这两个反转取消了。我包含它只是为了使结果与常用的(可能是最常用的)CRC-32 一致。

一种具有更多计算但允许 CRC 的任何起始值的替代方法是撤消末尾几个零的影响。在这种情况下,将五位保留在最低有效位中,将零保留在高位三位中,使用该字节和任何起始值计算 CRC,然后撤消最后三个零的影响。 C 中的这个例程就是这样做的:

uint32_t crc32unzeros(uint32_t crc, unsigned bits) {
    crc = ~crc;
    while (bits--)
        crc = crc & 0x80000000 ? ((crc ^ 0xedb88320) << 1) | 1 : crc << 1;
    return ~crc;
}

那么我们举个例子:

crc32unzeros(crc32zeros(8), 3) == crc32zeros(5)

【讨论】:

  • 这仅在 CRC 使用全 1 初始化时有效。假设,在第一个时钟周期我得到了 8 个有效位,在下一个时钟周期我得到了 5 个有效位,那么这个过程就会失败。因为现在将 8 位有效位 CRC 的结果而不是全 1 提供给设计。
  • 我在理解更新后的答案时遇到了一些麻烦。我的意思是,如何撤消零效应?假设我的数据是二进制“10101010_10101”,所以我会为我的 8 位并行 CRC 生成器提供数据“10101010”和 init_crc All-1s。然后,将结果作为 crc_init 连同新数据“10101”一起馈送到 CRC 生成器。现在我应该怎么做才能得到有效的结果?
  • 订阅10101010。然后喂00010101。 (不要弄乱它们之间的 CRC。)您现在拥有 0001010110101010 的 CRC,即 0x78eca277。然后撤消最后三个零的效果,得到1010110101010的CRC,即0x1c430639
  • >> 然后撤消最后三个零的效果
  • 谢谢,马克。问题是我试图在 VHDL 中实现它。它实际上是 10G 以太网的 CRC32 实现。我的数据是 8 字节的,我正在使用 8 字节并行 CRC 生成器。我正在使用来自 sigmatone.com/utilities/crc_generator/crc_generator.htm 的并行 CRC 生成器。您能否建议我一些更好的方法来为不是 8 字节的倍数的数据包大小实现 CRC32。我不确定如何在 VHDL 中实现 CRC32unzeros() 逻辑。我想在一个时钟周期内计算我的 CRC,这就是我使用并行 CRC 生成器的原因。
【解决方案2】:

一般来说,您不能使用简单的 n 位并行 CRC 计算器逻辑来并行计算 m 位上的 CRC。它可能在某些特殊情况下起作用,具体取决于多项式、数据集、初始值等。所以就像 @user1155120 已经提到的,您需要一个 5 位并行 CRC32 计算器来满足您的情况。

如果您需要计算不同位宽的并行 CRC,一种常见的解决方案是为您需要计算的每个位宽实现一个 n 位并行 CRC 计算器模块,并将计算器模块输出多路复用到 CRC 寄存器,具体取决于您的位有效/使能信号。

【讨论】:

  • 谢谢@DirkH。但这会消耗 FPGA 中的大量资源。我想保存一些。
猜你喜欢
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
  • 2021-03-18
相关资源
最近更新 更多