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 页校验、数据帧、外层检错
工程上常见的组合是“内层 SEC-DED + 外层 CRC”:内层负责纠正孤立位翻转,外层负责发现内层无法处理的残余错误,防止把错误数据当成正确数据使用。

五、一个可操作的设计示例

假设某星载 SRAM 存储阵列按 32 位字组织,要求纠正 1 位错、检测 2 位错。采用扩展汉明码 SEC-DED,可按以下步骤估算:

  1. 确定数据位 k = 32。
  2. 求满足 2r ≥ k + r + 1 的最小 r。r = 6 时 26 = 64 ≥ 32 + 6 + 1 = 39,成立;故基础汉明码需 6 位校验。
  3. 增加 1 位总校验位,得到 r = 7,码字长度 n = 39,实际按 39 位存储或补齐到 40 位。
  4. 冗余开销约为 7/32 ≈ 21.9%,即每 32 位数据额外存 7 位校验。
  5. 译码时计算 7 位伴随式:若伴随式指示单比特错误则纠正;若伴随式非零但不符合单比特错误图样,则判定为不可纠正错误,触发中断或重读。

若同一存储区还要求检测整页数据在传输中的突发错误,可在 512 字节页尾再附加 CRC32,形成“SEC-DED 纠错 + CRC 检错”的双层结构。此时写入路径需先算 SEC-DED 校验位,再对整页(含校验位)算 CRC;读取路径先验 CRC,再对每个 32 位字做 SEC-DED 译码。两层校验的先后顺序不能颠倒,否则 CRC 可能把已纠正的数据误判为错误。

星载存储编码保护链:写入与读取路径 写入路径 32 位数据字 k = 32 SEC-DED 编码 生成 7 位校验位 39 位码字 32 数据 + 7 校验 CRC32 计算 整页附加 4 字节 存储 阵列 读取路径 读取码字 含校验位 CRC32 校验 余数 = 0 ? SEC-DED 译码 计算 7 位伴随式 输出 32 位数据 或报不可纠正错 CRC 余数 ≠ 0 → 触发重读/上报 伴随式非零且 非单比特图样 伴随式 = 0 → 数据可信 关键参数(示例) 数据位 k = 32,SEC-DED 校验位 r = 7,码字 n = 39,冗余开销 ≈ 21.9% CRC32 生成多项式示例:0x04C11DB7,每 512 字节页附加 4 字节校验 纠错能力:SEC-DED 纠 1 位、检 2 位;CRC 检测长度 ≤ 32 的突发错误

需要强调的是,编码方案的选择必须与错误模型匹配。若存储器件的主要失效模式是整页擦除失败或长突发错误,单纯依赖 SEC-DED 会力不从心,此时应引入更强的纠错码(如 BCH、RS)或块级冗余;若错误以孤立位翻转为主,SEC-DED 加 CRC 的组合往往能以较低开销获得足够可靠的保护。实际工程中,还应结合器件手册给出的错误率、任务寿命和可接受的数据丢失概率,反推所需的最小码距和冗余预算,而不是直接套用某一固定方案。