Link-ECC代码思想
linkecc其实也是二分法的思想去找到错误的比特,低三位确定是byte中的哪个bit,[3:7]确定是128bit中的哪个byte。参考下面的代码所示:
写数据时的ECC逻辑
1.例化两个cadence_mc_memcd_link_eccw_data,分别根据lane0、lane1上的数据生成ecc校验位;
lecc_wrdata_lane0 -> lecc_wrdata_lecc_lane0
lecc_wrdata_lane1 -> lecc_wrdata_lecc_lane1
2.重点看一下9bit ecc校验码的生成逻辑
Data Byte Swirling:将128bit的write_data 翻转
- ecc_bits[0]:write_data_swirl & C0 表示取 write_data_swirl 的偶数位,接着按位异或;表示 write_data_swirl 的 [1,3,5,7,…,127] bit的按位异或结果;
- ecc_bits[1]:表示 write_data_swirl 的 [2,3,6,7…] bit的按位异或结果
- ecc_bits[2]:表示 write_data_swirl 的 [4,5,6,7…] bit的按位异或结果
…以此类推,相当于把 write_data_swirl 进行分组异或;其中ecc_bits[8]:全局奇偶校验位(扩展位,用于区分单 / 双比特错误)
读数据时的ECC逻辑
1.例化两个 cadence_mc_memcd_link_eccr_data,根据lane0、lane1的 read_data 以及 read_ecc_check_bits,实现单比特纠错 & 双比特检测
2.读通道的ecc matrix和写通道的ecc matrix完全一致
3.重点看9bit ecc校验码的校验逻辑
Data Byte Swirling:将128bit的 read_data 翻转
- syndrome[0]:read_data_swirl & C0 表示取 read_data_swirl 的偶数位,接着按位异或,接着与 read_check_bit[0] 异或;
其中read_check_bit[0] = ^(write_data_swirl & C0),所以 syndrome[0] = [^(read_data_swirl & C0)] ^ [^(write_data_swirl & C0)];
在不出错的情况下,read_data_swirl = write_data_swirl,所以syndrome[0] 结果应该是0;但是如果(read_data_swirl & C0)与(write_data_swirl & C0)值不一样,syndrome[0] 结果应该是1。
那么什么情况下(read_data_swirl & C0)与(write_data_swirl & C0)值不一样呢?
就是 read_data_swirl 在某一个 C0等于1的bit位上,数据发生错误翻转,就会导致 (read_data_swirl & C0) 与 (write_data_swirl & C0) 值不一样,从而导致syndrome[0] = 1 - syndrome[1]与前面类似:
read_data_swirl 在某一个 C1等于1的bit位上,数据发生错误翻转,就会导致 (read_data_swirl & C1) 与 (write_data_swirl & C1) 值不一样,从而导致syndrome[1] = 1 - syndrome[2]与前面类似:
read_data_swirl 在某一个 C2等于1的bit位上,数据发生错误翻转,就会导致 (read_data_swirl & C2) 与 (write_data_swirl & C2) 值不一样,从而导致syndrome[2] = 1
通过syndrome[0、1、2]就能判断是哪一个bit出现错误:
比如:syndrome[2:0]=010时,代表write_data_swirl & C0、write_data_swirl & C2没出错,但是write_data_swirl & C1出错了;
write_data_swirl & C2没出错表示write_data_swirl[4:7]bit没出错;
write_data_swirl & C0没出错表示write_data_swirl[1][3][5][7] bit没出错;
write_data_swirl & C1出错表示write_data_swirl[2][3][6][7] 其中一个bit发生错误翻转;
根据排除法可知,bit2发生错误翻转,对应write_data的bit[5]发生错误翻转;其他情况以此类推;
syndrome[7:3] 用来定位错误所在的byte
4.接着就是纠错逻辑根据e_beat、e_bit生成128bit的纠错掩码xor_word;
错误的位置使用1填充,没有发生错误的地方使用0填充;|(syndrome[8:0]):表示 syndrome[8:0] 的按位或,全0则表示没有ecc error,有一个以上1则表示存在ecc error;
存在ecc error时,进一步判断是单比特错误还是双比特错误: syndrome[8] = 1,表示128bit数据中只有1bit发生错误翻转;syndrome[8] = 0,表示有2bit发生错误翻转;这一点根据前面的表达式很容易理解,不做赘述。
如果是单比特错误(single_bit_error),那么将read_data_swirl与xor_word异或。1与任何数异或等价于取反,0与任何数异或结果不变。从而实现将错误的bit进行纠错。
ecc纠错只能实现单比特纠错、双比特检测。
但是对于3bit的错误无能为力,但是128bit中同时出现3个bit错误的概率极低,ecc纠错假设的前提就是认为这种场景不存在。