4. 错误检测纠正编码基础
星载存储器的错误检测与纠正,本质上是在“数据位”之外附加“校验位”,用冗余换取可靠性。线性分组码、汉明码和循环冗余校验(CRC)是三类最基础、也最常被组合使用的编码工具。理解它们的数学结构、纠错能力和工程代价,是判断“某段存储该用哪种保护”的前提。
一、线性分组码:把校验写成矩阵运算
线性分组码把信息位分成固定长度的组,每组 k 位信息位映射为 n 位码字(n > k),附加 r = n − k 位校验位。其“线性”体现在:任意两个合法码字逐位异或,结果仍是合法码字。这一性质使编码和译码都可以用二元矩阵运算描述。
设信息向量为 m(1×k),生成矩阵为 G(k×n),则码字 c = m·G(模 2 运算)。校验矩阵 H(r×n)满足 G·HT = 0,因此合法码字必然满足 c·HT = 0。接收端计算伴随式 s = r·HT:若 s = 0,认为无错;若 s ≠ 0,则 s 直接指示错误图样。码的最小汉明距离 dmin 决定能力:可检测 dmin − 1 位错误,可纠正 ⌊(dmin − 1)/2⌋ 位错误。
在星载存储中,线性分组码的价值在于“结构可控”:给定目标纠错位数 t,就能反推所需校验位数 r,从而估算冗余开销。例如要求纠正 1 位错,通常需要满足 2r ≥ n + 1;要求纠正 2 位错并检测 3 位错(SEC-DED),则需在汉明码基础上再增加 1 位总校验位。
二、汉明码:单比特纠错的经典实现
汉明码是最典型的线性分组码,校验位放在 2 的幂次位置(第 1、2、4、8…位),每个校验位负责一组特定数据位的奇偶校验。以 (7,4) 汉明码为例:4 位数据 d1d2d3d4,3 位校验 p1p2p3,码字共 7 位。校验关系为:
p1 = d1 ⊕ d2 ⊕ d4
p2 = d1 ⊕ d3 ⊕ d4
p3 = d2 ⊕ d3 ⊕ d4
译码时重新计算三个校验方程,得到 3 位伴随式,其二进制值直接指向出错位的位置(0 表示无错)。例如伴随式为 101(十进制 5),说明第 5 位出错,取反即可纠正。这种“伴随式即错误地址”的特性,使汉明码译码逻辑非常简洁,适合用组合逻辑或查表实现。
星载存储中更常用的是扩展汉明码 SEC-DED:在 (7,4) 基础上增加一位总校验位,形成 (8,4) 码,可纠正 1 位错、检测 2 位错。对于 SRAM 型星载存储器,单粒子翻转(SEU)通常表现为孤立单比特错误,SEC-DED 能以约 8/4 = 2 倍的位开销提供足够保护,是许多星载计算机存储阵列的默认选择。但要注意:若同一码字内出现两位翻转,SEC-DED 只能检测而无法纠正,此时需要更高级的纠错或重读机制。
三、循环冗余校验:面向突发错误的检错利器
CRC 把数据位串看作 GF(2) 上的多项式,用生成多项式 G(x) 去除 xr·M(x),余数即为 r 位校验值。接收端用同一 G(x) 除接收码字,余数为 0 则认为无错。CRC 的强项是检测突发错误:一个 r 阶生成多项式可检测所有长度 ≤ r 的突发错误,以及大多数更长的突发错误。
星载存储中 CRC 常用于三类场景:一是存储器页或块的完整性校验,例如 NAND Flash 每 512 字节附加 4 字节 CRC32;二是遥测遥控数据帧的端到端校验;三是作为纠错码的“外层”配合,先用汉明码纠随机错,再用 CRC 检测残余错误,避免误纠。CRC 的代价是只检不纠,一旦发现错误通常需要重读或请求重传,因此它更适合“错误率低、可重试”的通道,而不适合无法重试的实时存储写入路径。
四、三类编码在星载存储中的适用性对比
选择编码方案时,需要同时看错误模型、纠错能力、冗余开销和实现复杂度。下表给出面向星载存储的定性对比(参数为典型示例,实际设计需按器件与任务剖面核算):
| 编码类型 | 典型能力 | 冗余开销 | 译码复杂度 | 星载存储适用场景 |
|---|---|---|---|---|
| 线性分组码 | 按 dmin 可设计纠 t 位 | 中~高 | 中(矩阵运算) | 需要定制纠错能力的存储阵列 |
| 汉明码 / SEC-DED | 纠 1 位、检 2 位 | 低(约 1.5~2 倍) | 低(异或/查表) | SRAM、寄存器堆、Cache 行 |
| CRC | 检突发错,不纠错 | 低(4 字节/512 字节) | 低(移位异或) | Flash 页校验、数据帧、外层检错 |
五、一个可操作的设计示例
假设某星载 SRAM 存储阵列按 32 位字组织,要求纠正 1 位错、检测 2 位错。采用扩展汉明码 SEC-DED,可按以下步骤估算:
- 确定数据位 k = 32。
- 求满足 2r ≥ k + r + 1 的最小 r。r = 6 时 26 = 64 ≥ 32 + 6 + 1 = 39,成立;故基础汉明码需 6 位校验。
- 增加 1 位总校验位,得到 r = 7,码字长度 n = 39,实际按 39 位存储或补齐到 40 位。
- 冗余开销约为 7/32 ≈ 21.9%,即每 32 位数据额外存 7 位校验。
- 译码时计算 7 位伴随式:若伴随式指示单比特错误则纠正;若伴随式非零但不符合单比特错误图样,则判定为不可纠正错误,触发中断或重读。
若同一存储区还要求检测整页数据在传输中的突发错误,可在 512 字节页尾再附加 CRC32,形成“SEC-DED 纠错 + CRC 检错”的双层结构。此时写入路径需先算 SEC-DED 校验位,再对整页(含校验位)算 CRC;读取路径先验 CRC,再对每个 32 位字做 SEC-DED 译码。两层校验的先后顺序不能颠倒,否则 CRC 可能把已纠正的数据误判为错误。
需要强调的是,编码方案的选择必须与错误模型匹配。若存储器件的主要失效模式是整页擦除失败或长突发错误,单纯依赖 SEC-DED 会力不从心,此时应引入更强的纠错码(如 BCH、RS)或块级冗余;若错误以孤立位翻转为主,SEC-DED 加 CRC 的组合往往能以较低开销获得足够可靠的保护。实际工程中,还应结合器件手册给出的错误率、任务寿命和可接受的数据丢失概率,反推所需的最小码距和冗余预算,而不是直接套用某一固定方案。