ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现

2021-06-06 15:59:43  阅读:534  来源: 互联网

标签:ecc Flash 校验 算法 input ECC 256 reg


目录:
1: ECC原理
2: ECC校验-列校验
3: ECC校验-行校验
4: ECC校验结果的分析
5: 算法实现
6: 实例分析
7: 校验流程总结
8:硬件verilog代码

1.ECC校验原理
先看下奇偶校验:
奇校验: 一个字节有8位, 校验位1位, 共9位, 使9位中“ 1” 的个数为奇数;
偶校验: 同理。
奇偶校验缺点 : 1.奇偶校验每传输一个字节都需要加一位校验位, 对传输效率影响很大。
2.不能把纠正错误。
奇偶校验示意图
ECC校验:
从NAND Flash读取数据时, Page( 存储数据的基本单元, 如256+8 byte) 中的1个或几个bit可能会出现错误, 每256字节我们生成一个ECC校验和, 称之为新ECC校验和。 ECC能纠正单比特错误和检测双比特错误, 而且计算速度很快, 但对1比特以上的错误无法纠正, 对2比特以上的错误不保证能检测。

生成ECC校验码的算法:
ECC 校验每次对 256 Byte的数据进行操作, 包含列校验和行校验。 对每个待校验的 Bit 位求异或, 若结果为 0 , 则表明含有偶数个 1 ; 若结果为 1 , 则表明含有奇数个 1 。 256 字节数据形成 256 行、 8 列的矩阵, 矩阵每个元素表示一个 Bit 位。
行列校验示意图

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
8.硬件verilog实现

module ECCChckMod(
				input		    clk50M,
				input    		rst,
					 
				input		    [7:0] DataIn,
				input           DataInEn,
				input           EccStart,
				input           [15:0]DataNum,

				output reg      [31:0]ECCDataOut,
				output reg		ECCDaOutEn

);

reg	[2:0 ]	state;
reg         ecc_P1, ecc_P2, ecc_P4, ecc_P8, ecc_P16, ecc_P32, ecc_P64, ecc_P128, ecc_P256, ecc_P512, ecc_P1024, ecc_P2048, ecc_P4096, ecc_P8192;
reg         ecc_P1x,ecc_P2x,ecc_P4x,ecc_P8x,ecc_P16x,ecc_P32x,ecc_P64x,ecc_P128x,ecc_P256x,ecc_P512x,ecc_P1024x,ecc_P2048x,ecc_P4096x,ecc_P8192x;
reg         S_P8,S_P16,S_P32,S_P64,S_P128,S_P256,S_P512,S_P1024,S_P2048,S_P4096;
reg [15:0]  DataCnt;

wire  [7:0] d;
assign      d= DataIn;
	
always@(posedge clk50M or posedge rst)
	if(rst)begin
		state<=3'h0;
		ecc_P1<=1'b0;
		ecc_P2<=1'b0;
		ecc_P4<=1'b0;
		ecc_P8<=1'b0;
		ecc_P16<=1'b0;
		ecc_P32<=1'b0;
		ecc_P64<=1'b0;
		ecc_P128<=1'b0;
		ecc_P256<=1'b0;
		ecc_P512<=1'b0;
		ecc_P1024<=1'b0;
		ecc_P2048<=1'b0;
		ecc_P4096<=1'b0;
		ecc_P8192<=1'b0;
		ecc_P1x<=1'b0;
		ecc_P2x<=1'b0;
		ecc_P4x<=1'b0;
		ecc_P8x<=1'b0;
		ecc_P16x<=1'b0;
		ecc_P32x<=1'b0;
		ecc_P64x<=1'b0;
		ecc_P128x<=1'b0;
		ecc_P256x<=1'b0;
		ecc_P512x<=1'b0;
		ecc_P1024x<=1'b0;
		ecc_P2048x<=1'b0;
		ecc_P4096x<=1'b0;
		ecc_P8192x<=1'b0;
		S_P8<=1'b0;
		S_P16<=1'b0;
		S_P32<=1'b0;
		S_P64<=1'b0;
		S_P128<=1'b0;
		S_P256<=1'b0;
		S_P512<=1'b0;
		S_P1024<=1'b0;
		S_P2048<=1'b0;
		S_P4096<=1'b0;
		DataCnt<=16'h0;
		ECCDataOut<=32'h0;
		ECCDaOutEn<=1'b0;
	end
	else begin
		case(state)
			3'h0:
				if(EccStart==1'b1)
					state<=3'h1;
				else 
					state<=3'h0;
			3'h1:
				if(DataNum==16'd2052)begin     //计数满2K
					state<=3'h2;
					ecc_P1<=1'b0;
					ecc_P2<=1'b0;
					ecc_P4<=1'b0;
					ecc_P8<=1'b0;
					ecc_P16<=1'b0;
					ecc_P32<=1'b0;
					ecc_P64<=1'b0;
					ecc_P128<=1'b0;
					ecc_P256<=1'b0;
					ecc_P512<=1'b0;
					ecc_P1024<=1'b0;
					ecc_P2048<=1'b0;
					ecc_P4096<=1'b0;
					ecc_P8192<=1'b0;
					ecc_P1x<=1'b0;
					ecc_P2x<=1'b0;
					ecc_P4x<=1'b0;
					ecc_P8x<=1'b0;
					ecc_P16x<=1'b0;
					ecc_P32x<=1'b0;
					ecc_P64x<=1'b0;
					ecc_P128x<=1'b0;
					ecc_P256x<=1'b0;
					ecc_P512x<=1'b0;
					ecc_P1024x<=1'b0;
					ecc_P2048x<=1'b0;
					ecc_P4096x<=1'b0;
					ecc_P8192x<=1'b0;
					DataCnt<=16'h0;
				end
				else 
					state<=3'h0;
			3'h2:begin
				if(DataCnt==16'd2048)begin //校验2k数据
					state<=3'h3;
					DataCnt<=16'h0;
					ECCDataOut<={ecc_P8192, ecc_P4096, ecc_P2048, ecc_P1024, ecc_P512, ecc_P256, ecc_P128, ecc_P64, ecc_P32, ecc_P16, ecc_P8, ecc_P4,ecc_P2,ecc_P1,
								 ecc_P8192x,ecc_P4096x,ecc_P2048x,ecc_P1024x,ecc_P512x,ecc_P256x,ecc_P128x,ecc_P64x,ecc_P32x,ecc_P16x,ecc_P8x,ecc_P4x,
								 ecc_P2x,ecc_P1x,1'b1,1'b1,1'b1,1'b1};
					ECCDaOutEn<=1'b1;
				end
				else if(DataInEn==1'b1)begin //计数直到2K个数据进来
					DataCnt<=DataCnt + 1'b1;
					state<=3'h2;
				end
				//P1,P2,P4,P1x,P2x,P4x
				if(DataInEn==1'b1)begin    //列校验
					ecc_P1<=d[1]^d[3]^d[5]^d[7]^ecc_P1;
					ecc_P1x<=d[0]^d[2]^d[4]^d[6]^ecc_P1x;
					ecc_P2<=d[2]^d[3]^d[6]^d[7]^ecc_P2;
					ecc_P2x<=d[0]^d[1]^d[4]^d[5]^ecc_P2x;
					ecc_P4<=d[4]^d[5]^d[6]^d[7]^ecc_P4;
					ecc_P4x<=d[0]^d[1]^d[2]^d[3]^ecc_P4x;
				end
				//P8 以下是行校验
				if(DataInEn==1'b1 && DataCnt[0]==1'b1)begin
					ecc_P8<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^ecc_P8;
				end
				//P8x
				if(DataInEn==1'b1 && DataCnt[0]==1'b0)begin
					ecc_P8x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^ecc_P8x;
					S_P8<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7];
				end
				//P16
				if(DataInEn==1'b1 && DataCnt[1:0]==2'b11)begin
					ecc_P16<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^ecc_P16;
				end
				//P16x
				if(DataInEn==1'b1 && DataCnt[1:0]==2'b01)begin
					ecc_P16x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^ecc_P16x;
					S_P16<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8;
				end
				//P32
				if(DataInEn==1'b1 && DataCnt[2:0]==3'b111)begin
					ecc_P32<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^ecc_P32;
				end
				//P32x
				if(DataInEn==1'b1 && DataCnt[2:0]==3'b011)begin
					ecc_P32x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^ecc_P32x;
					S_P32<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16;
				end
				//P64
				if(DataInEn==1'b1 && DataCnt[3:0]==4'b1111)begin
					ecc_P64<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^ecc_P64;
				end
				//P64x
				if(DataInEn==1'b1 && DataCnt[3:0]==4'b0111)begin
					ecc_P64x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^ecc_P64x;
					S_P64<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32;
				end
				//P128
				if(DataInEn==1'b1 && DataCnt[4:0]==5'b11111)begin
					ecc_P128<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^ecc_P128;
				end
				//P128x
				if(DataInEn==1'b1 && DataCnt[4:0]==5'b01111)begin
					ecc_P128x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^ecc_P128x;
					S_P128<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64;
				end
				//P256
				if(DataInEn==1'b1 && DataCnt[5:0]==6'b111111)begin
					ecc_P256<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^ecc_P256;
				end
				//P256x
				if(DataInEn==1'b1 && DataCnt[5:0]==6'b011111)begin
					ecc_P256x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^ecc_P256x;
					S_P256<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128;
				end
				//P512
				if(DataInEn==1'b1 && DataCnt[6:0]==7'b1111111)begin
					ecc_P512<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^ecc_P512;
				end
				//P512x
				if(DataInEn==1'b1 && DataCnt[6:0]==7'b0111111)begin
					ecc_P512x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^ecc_P512x;
					S_P512<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256;
				end
				//P1024
				if(DataInEn==1'b1 && DataCnt[7:0]==8'b11111111)begin
					ecc_P1024<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^ecc_P1024;
				end
				//P1024x
				if(DataInEn==1'b1 && DataCnt[7:0]==8'b01111111)begin
					ecc_P1024x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^ecc_P1024x;
					S_P1024<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512;
				end
				//P2048
				if(DataInEn==1'b1 && DataCnt[8:0]==9'b111111111)begin
					ecc_P2048<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^S_P1024^ecc_P2048;
				end
				//P2048x
				if(DataInEn==1'b1 && DataCnt[8:0]==9'b011111111)begin
					ecc_P2048x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^S_P1024^ecc_P2048x;
					S_P2048<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^S_P1024;
				end
				//P4096
				if(DataInEn==1'b1 && DataCnt[9:0]==10'b1111111111)begin
					ecc_P4096<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^S_P1024^S_P2048^ecc_P4096;
				end
				//P4096x
				if(DataInEn==1'b1 && DataCnt[9:0]==10'b0111111111)begin
					ecc_P4096x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^S_P1024^S_P2048^ecc_P4096x;
					S_P4096<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^S_P1024^S_P2048;
				end
				//P8192
				if(DataInEn==1'b1 && DataCnt[10:0]==11'b11111111111)begin
					ecc_P8192<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^S_P1024^S_P2048^S_P4096^ecc_P8192;
				end
				//P4096x
				if(DataInEn==1'b1 && DataCnt[10:0]==11'b01111111111)begin
					ecc_P8192x<=d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^S_P8^S_P16^S_P32^S_P64^S_P128^S_P256^S_P512^S_P1024^S_P2048^S_P4096^ecc_P8192x;
				end
			end
			3'h3:begin
				ECCDaOutEn<=1'b0;
				state<=3'h4;
			end
			3'h4:
				state<=3'h0;
			default:
				state<=3'h0;
		endcase
	end
		
endmodule 

标签:ecc,Flash,校验,算法,input,ECC,256,reg
来源: https://blog.csdn.net/weixin_42672920/article/details/117628367

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有