14
CRC32 控制器
14.1 概述
在 8 位计算机上验证数据完整性(例如在刷新固件之前或从不可靠的接口接收数据之后)可能具有挑战性。 简单的校验和(如 CRC8 或 CRC16)在错误检测方面可能不够充分,或者在处理大量数据时速度过慢。
为简化此过程,Zeal Video Board 包含一个硬件 CRC32 控制器,可将计算工作从主机处理器中卸载。
与其他控制器一样,CRC32 控制器可以映射到 I/O 端口上起始地址为 0xA0 的设备分片中。其设备索引为 2。
14.2 计算校验和
计算数据块的 CRC32 可按以下步骤进行:
-
复位控制器:
- 将
CTRL寄存器中的RESET位设置为1。 - 复位是立即执行的,该位由硬件自动清除 — 无需将其写回
0。 - 这将内部 32 位 CRC 寄存器初始化为
0xFFFFFFFF。
- 将
-
输入数据:
- 每次一个字节地将数据块的每个字节写入
DATAIN寄存器。
- 每次一个字节地将数据块的每个字节写入
-
读取结果:
- 写入所有字节后,可以从以下寄存器读取最终的 32 位 CRC 值:
CRC32_BYTE0— 最低有效字节(LSB)CRC32_BYTE1CRC32_BYTE2CRC32_BYTE3— 最高有效字节(MSB)
- 这些寄存器为只读。
- 写入所有字节后,可以从以下寄存器读取最终的 32 位 CRC 值:
用于计算的多项式为 0xEDB88320。
时序说明: 写入每个字节后,Zeal Video Board 需要 2 个时钟周期(@ 50 MHz)来更新 CRC。 由于典型的 8 位处理器运行速度要慢得多,因此写入之间不需要额外的延迟或
nop指令。
14.3 示例(Z80)
假设我们有一个基于 Z80 的主机系统,并且 CRC32 控制器映射在 0xA0 I/O 分片中。计算 HL 指向的字节数组的 CRC32 可以按如下方式完成:
; 参数:
; HL - 字节数组
; BC - 数组大小
; 返回值:
; DEHL - 32 位 CRC32
calculate_crc32:
; 复位控制器
ld a, 1
out (0xa0), a
; 将所有字节写入 `DATAIN`(偏移量 1)。
; 我们可以使用 `otir` 指令,但为了保持示例简洁,这里不使用。
_crc32_next_byte:
; 检查 BC 是否为 0,如果为 0 则结束。
ld a, b
or c
jr z _crc32_end
ld a, (hl)
out (0xa1), a
inc hl
dec bc
jr _crc32_next_byte
_crc32_end:
; 读取结果 CRC32
in a, (0x4)
ld l, a
in a, (0x5)
ld h, a
in a, (0x6)
ld e, a
in a, (0x7)
ld d, a
ret
14.4 寄存器总览
| Name | Description | Base-relative address | Access |
| CTRL | CRC32控制器的控制寄存器 | 0x00 | WO |
| DATAIN | CRC计算的输入数据字节 | 0x01 | WO |
| CRC32_BYTE0 | CRC32结果字节0(最低字节) | 0x04 | RO |
| CRC32_BYTE1 | CRC32结果字节1 | 0x05 | RO |
| CRC32_BYTE2 | CRC32结果字节2 | 0x06 | RO |
| CRC32_BYTE3 | CRC32结果字节3(最高字节) | 0x07 | RO |
14.5 寄存器
CTRL (0x00)
CRC32控制器的控制寄存器
(reserved)
RESET
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Reset
RESET
重置CRC32控制器状态,应在计算新数据集的校验和之前执行 (WO)
DATAIN (0x01)
CRC计算的输入数据字节
DATA
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Reset
DATA
输入到CRC32计算的输入数据字节 (WO)
CRC32_BYTE0 (0x04)
CRC32结果字节0(最低字节)
DATA
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Reset
DATA
计算出的CRC32值的最低字节 (RO)
CRC32_BYTE1 (0x05)
CRC32结果字节1
DATA
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Reset
DATA
计算出的CRC32值的第1字节 (RO)
CRC32_BYTE2 (0x06)
CRC32结果字节2
DATA
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Reset
DATA
计算出的CRC32值的第2字节 (RO)
CRC32_BYTE3 (0x07)
CRC32结果字节3(最高字节)
DATA
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Reset
DATA
计算出的CRC32值的最高字节 (RO)