ECC校验算法
之前做笔试题的时候有碰到ECC的题,但我之前只知道CRC。
CRC(循环冗余校验,Cyclic redundancy check)主要用于数据传输过程中的检测。而ECC(Error Checking and Correcting)则主要应用在数据存储领域。
ECC算法
存入数据的同时写入ECC校验值,在读取时计算ECC校验值,两相比较,即可知道存储是否发生变化。
出现多 bit错误的概率较小,所以主流:
- DED (Double Error Dection):可检测双bit错误
- SECDED (Single Error Correct Double Error Dection):可检测单bit错误(并纠正),检测双bits错误(不可纠正)
NandFlash的ECC校验算法[1]
对于 1byte 8bits的数据,校验如下:
[7] | [6] | [5] | [4] | [3] | [2] | [1] | [0] |
---|
偶校验值:ECCe[2:0] = {3 ⊕ 2 ⊕ 1 ⊕ 0, 5 ⊕ 4 ⊕ 1 ⊕ 0, 6 ⊕ 4⊕ 2 ⊕ 0}
奇校验值:ECCo[2:0] = {7 ⊕ 6 ⊕ 5 ⊕ 4, 7 ⊕ 6 ⊕ 3 ⊕ 2, 7 ⊕ 5 ⊕3 ⊕ 1}
通过ECCe(2) / ECCo(2),可以判断错误发生在0-8bit的左半部分还是右半部分
通过ECCe(1) / ECCo(1),可以判断错误发生已确定的4bit中的左半部分还是右半部分
通过ECCe(0) / ECCo(0),即可确认出错的具体bit
校验是否发生错误
Error[2:0]=ECCe ⊕ ECCo ⊕ ECCe’ ⊕ ECCo’
‘111’为发生1为错误,‘000’为完全正确
校验错误的地址
Error_Loc[2:0]=ECCo ⊕ ECCo’
Error_Loc[2:0]的值即代表错误地址
海明码[2]
求信息 1011 的海明码
第 1 步 求校验码位数
牢记公式:2^r >= k + r + 1
k
值:原始信息码的位数,已知r
值:校验码的位数,根据公式
第 2 步 确认校验码位置
校验码的位置都是基于 2^n
来确定的,比如 2^0 = 1,2^1 = 2,2^2 = 4…
① 海明码的长度 = 原始信息码 + 校验码
此题中,海明码长度 = 4 + 3 = 7 位
② 建立一个从高位到低位的表格,表格列数即为海明码的长度
先填校验码,在本题中,校验码为 3 位,即占了 1、2、4 位,这里以 r0、r1、r2 来表示校验码
再填信息码,从高位往低位顺序填上信息码,即从左到右,注意要跳过校验码
7 | 6 | 5 | 4 | 3 | 2 | 1 | 位数 |
---|---|---|---|---|---|---|---|
1 | 0 | 1 | 1 | 信息位 | |||
r2 | r1 | r0 | 校验位 |
第 3 步 计算校验码
① 将每个信息位数拆分成 n 个校验位数之和
在本题中,信息位是:7、6、5、3,校验位是:4、2、1,则
7 = 4 + 2 + 1,表示第 7 位的信息码由第 4、2、1 位的校验码所校验,下同
6 = 4 + 2,
5 = 4 + 1
3 = 2 + 1
② 分组
将上面等式中,各个校验码所校验的位数进行分组
如 r2 是第 4 位,而 4 校验了上面的 7、6、5 位,可以写成
r2(7,6,5)
r1(7,6,3)
r0(7,5,3)
③计算
将分组的元素转为该位置对应的信息码再进行异或运算即可
注意,是异或运算,即同 0 异 1 的原则
r2 = 1 ⊕ 0 ⊕ 1 = 0
r1 = 1 ⊕ 0 ⊕ 1 = 0
r0 = 1 ⊕ 1 ⊕ 1 = 1
第 4 步 得到海明码
还记得上一张表吗,将校验码的位数的值填进去,就是一个海明码了
7 | 6 | 5 | 4 | 3 | 2 | 1 | 位数 |
---|---|---|---|---|---|---|---|
1 | 0 | 1 | 0 | 1 | 0 | 1 | 信息位 |
r2 | r1 | r0 | 校验位 |
参考来源
[1]深入浅出NandFlash里的ECC校验算法原理与实现(1)-CSDN博客