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

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

1.ECC校验原理
先看下奇偶校验:
奇校验: 一个字节有8位, 校验位1位, 共9位, 使9位中“ 1” 的个数为奇数;
偶校验: 同理。
奇偶校验缺点 : 1.奇偶校验每传输一个字节都需要加一位校验位, 对传输效率影响很大。
2.不能把纠正错误。
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
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 位。
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现

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

基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
基于Flash的ECC纠错算法基本原理及软件C语言算法和硬件Verilog实现
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 

上一篇:腾讯云SSL证书RSA算法和ECC算法区别对比及选择攻略


下一篇:椭圆曲线密码学:简介