OpenCores
URL https://opencores.org/ocsvn/reed_solomon_decoder/reed_solomon_decoder/trunk

Subversion Repositories reed_solomon_decoder

[/] [reed_solomon_decoder/] [trunk/] [rtl/] [error_correction.v] - Rev 2

Compare with Previous | Blame | View Log

/* This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
   Email : semiconductors@varkongroup.com
   Tel   : 1-732-447-8611
 
*/
 
 
module error_correction
//// evaluate error values, locations and correct it
(
 
input clk, // input clock planned to be 56 Mhz
input reset, // active high asynchronous reset
 
 
//active high flag for one clock to indicate that Phy and Omega polynomials are ready
input poly_ready ,
// decimal value of first coeff of Omega polynomial  
input  [7:0] O1,    
/// power values of omega polynomial coeff from 2:16
input  [7:0] O2,O3,O4,O5,O6,O7,O8,O9,O10,O11,O12,O13,O14,O15,O16,  
input [7:0] P1,    // decimal value of first coeff of Phy polynomial
input [7:0] P3,P5,P7,  /// power values of Phy polynomial coeff 
 
input roots_ready, // output active high flag to indicate that all roots is ready
input [3:0] root_count, ///  up to 8
input [7:0] r1,r2,r3,r4,r5,r6,r7,r8, // roots of lamda polynomial up to 8 roots
 
input [7:0] pow1,pow2,pow3,pow4,    /// output of power memories
input [7:0] dec1,dec2,dec3, dec4,        /// output of decimal memories
 
output reg [7:0] add_pow1,add_pow2,add_pow3,add_pow4, /// address to power memories
output  [7:0] add_dec1,add_dec2,add_dec3,add_dec4,  /// address to decimal memories
 
output RE,WE,    //// Write and read enable for input block storage memory
output reg [7:0] Address,   //// address to input block storage memory
//// corrected value  =  initial value xor  correction
output reg [7:0] correction_value,     
input [7:0] initial_value,  //// input initial value
 
output reg DONE
 
);
 
 
reg WE_0,RE_0;
 
reg [3:0] r_cnt;    ///   root count
reg [7:0] rd [1:8];   /// roots decimal values
reg [7:0] rp [1:8];  //// roots power values
reg [7:0] O [1:16]; //// omega poly
reg [7:0] P [1:4];  //// phy poly
 
reg [7:0] eL [1:8];    /// locations of errors 
reg [7:0] eV [1:8];   //// power values to evaluate to get correction values
 
 
reg [7:0] V;
reg [8:0] Vx2;
reg [9:0] Vx3;
reg [10:0] Vx6;
reg [10:0] Vx7;
reg [10:0] Vx8;
reg [11:0] Vx9;
 
 
reg [11:0] add1,add2,add3,add4;
reg [8:0] add_1,add_2,add_3,add_4;
 
 
reg IS_255_1,IS_255_2,IS_255_3,IS_255_4;
reg IS_255_1_delayed,IS_255_2_delayed,IS_255_3_delayed,IS_255_4_delayed;
reg div1;
 
reg [7:0] OV,PV;   
////// OV ==> evalute omega in decimal format
////// PV ==> evalute phy in decimal format
reg [3:0] cnt ;
 
reg [3:0] op_cnt;  
 
parameter state1  = 7'b0000001;
parameter state2  = 7'b0000010;
parameter state3  = 7'b0000100;
parameter state4  = 7'b0001000;
parameter state5  = 7'b0010000;
parameter state6  = 7'b0100000;
parameter state7  = 7'b1000000;
 
 
reg [6:0] state = state1;
 
integer k;
reg in_range;
//////////////////////////  assigns /////////////////////////////////
assign RE = RE_0 ;
assign WE =(WE_0  &&   ( Address < 188)  && in_range) ? 1:0;
 
 
 
//// to handle mutipilcation / division output (address to decimal memory)
assign add_dec1  =(IS_255_1_delayed)?  8'h00 :
				 (&add_1[7:0] && !add_1[8])?     8'h01 : 
				 (div1)? add_1[7:0] - (add_1[8]) +1 : 
				 add_1[7:0] +add_1[8] +1 ;
 
assign add_dec2  =(IS_255_2_delayed)?  8'h00 :
				  (&add_2[7:0] )?      8'h01 : 
				  add_2[7:0] +add_2[8] +1 ;
 
assign add_dec3  =(IS_255_3_delayed)?  8'h00 :
		          (&add_3[7:0] )?      8'h01 : 
				  add_3[7:0] +add_3[8] +1 ;
 
assign add_dec4  =(IS_255_4_delayed)?  8'h00 :
			      (&add_4[7:0] )?      8'h01 : 
				  add_4[7:0] +add_4[8] +1 ;
 
always@(posedge clk or posedge reset)
begin
	if(reset)
		begin
 
			for(k=1;k<=16;k=k+1)
				begin
					O[k] <=0;
				end
 
			for(k=1;k<=8;k=k+1)
				begin
					rd[k]<=0;
					rp[k]<=0;
				end
 
			for(k=1;k<=4;k=k+1)
				begin
					P[k]<=0;
				end
 
			for(k=1;k<=8;k=k+1)
				begin
					eL[k]<=0;
					eV[k]<=0;
				end	
 
			 WE_0<=0;RE_0<=0;
 
			r_cnt<=0;	
 
			 V<=0;
			 Vx2<=0;
			 Vx3<=0;
			 Vx6<=0;
			 Vx7<=0;
			 Vx8<=0;
			 Vx9<=0;
 
 
			 add1<=0;add2<=0;add3<=0;add4<=0;
			 add_1<=0;add_2<=0;add_3<=0;add_4<=0;
			 IS_255_1<=0;IS_255_2<=0;IS_255_3<=0;IS_255_4<=0;
			 IS_255_1_delayed<=0;IS_255_2_delayed<=0;
			 IS_255_3_delayed<=0;IS_255_4_delayed<=0;
			 div1<=0;
 
			 in_range<=0;
			 cnt <=0;
			 op_cnt <=0;
 
			add_pow1<=0;add_pow2<=0;add_pow3<=0;add_pow4<=0;
 
			Address<=0;
			correction_value<=0;
			DONE<=0;
 
			OV<=0;PV<=0;
			state<= state1;
		end
	else
		begin
		case(state)
		///////////////////////////////////////////////////////////
		state1:begin   /// register inputs
 
			for(k=1;k<=8;k=k+1)
				begin
					eL[k]<=188;
					eV[k]<=0;
				end	
 
 
			if(poly_ready)
				begin
					O[1]<=O1;O[2]<=O2;O[3]<=O3;O[4]<=O4;O[5]<=O5;O[6]<=O6;
					O[7]<=O7;O[8]<=O8;     
					O[9]<=O9;O[10]<=O10;O[11]<=O11;O[12]<=O12;O[13]<=O13;
					O[14]<=O14;O[15]<=O15;O[16]<=O16;
 
					P[1]<=P1;P[2]<=P3;P[3]<=P5;P[4]<=P7;
					end
 
			if(roots_ready)
				begin
					r_cnt<= root_count;
					rd[1]<=r1;rd[2]<=r2;rd[3]<=r3;rd[4]<=r4;
					rd[5]<=r5;rd[6]<=r6;rd[7]<=r7;rd[8]<=r8;
					state<=state2;
				end
 
 
		end
		////////////////////////////////////////////////////////
		state2:begin   /// convert roots to power values
			if(cnt == 3 )
				begin
					cnt<=1;
					state<=state3;
				end
			else
				cnt<=cnt+1;
			/////////////////////////////////////////////////////	
			case(cnt)
 
			0:begin
				add_pow1<=rd[1];
				add_pow2<=rd[2];
				add_pow3<=rd[3];
				add_pow4<=rd[4];
			end			
 
			1:begin
				add_pow1<=rd[5];
				add_pow2<=rd[6];
				add_pow3<=rd[7];
				add_pow4<=rd[8];
			end			
 
			2:begin
				rp[1]<=pow1;
				rp[2]<=pow2;
				rp[3]<=pow3;
				rp[4]<=pow4;
			end			
 
			default:begin
				rp[5]<=pow1;
				rp[6]<=pow2;
				rp[7]<=pow3;
				rp[8]<=pow4;
			end			
 
			endcase
		end
		/////////////////////////////////////////////////
		state3:begin   //// allocate eL,eV
			if(cnt == r_cnt)
				begin
					cnt<=0;
					state<=state4;
					op_cnt <=0;
				end
			else
				cnt<=cnt+1;
			///////////////////////////////////////
					eL[cnt]<=(rp[cnt]==0)?0:255-rp[cnt];
					// 0 is a special case
					// error location = inverse power value of root
					eV[cnt]<=rp[cnt];				
		end
		////////////////////////////////////////////////////////
		////// work with the roots one by one 
		state4:begin
			if(cnt==0)
				begin
					op_cnt<=op_cnt+1;
					cnt<=1;
					WE_0<=0;
				end
			else
				begin
 
					if(op_cnt > r_cnt)
						begin
							in_range<=0;
						end
					else	
						begin
							in_range <= 1;
						end
 
 
					if(op_cnt == 9)
						begin
							DONE<=1;
							cnt<=0;
							state<=state7;
						end
					else
						begin
							state<=state5;
							Address<=203-eL[op_cnt];
							RE_0<=1;
							V<= eV[op_cnt];
							Vx2<= eV[op_cnt]+eV[op_cnt];
							Vx3<= eV[op_cnt]+eV[op_cnt]+eV[op_cnt];
							cnt<=0;
 
							div1<=0;
							OV<=O[1];
							PV<=P[1];
							correction_value<=0;
						end
				end
		end
		///////////////////////////////////////////////
		state5:begin   /// main operation
			if(cnt == 7)
				begin
					cnt<=0;
					state<=state6;
				end
			else
				cnt<=cnt+1;
			///////////////////////////////////////
			RE_0<=0;
 
			Vx6<=Vx3+Vx3;    /// ready at 1 
			Vx7<=Vx6+V;       /// ready at 2
			Vx8<=Vx6+Vx2;   /// ready at 2
			Vx9<=Vx6+Vx3;   /// ready at 2
 
			IS_255_1_delayed<=IS_255_1;
			IS_255_2_delayed<=IS_255_2;
			IS_255_3_delayed<=IS_255_3;
			IS_255_4_delayed<=IS_255_4;
 
			add_1<= add1[11:8]+add1[7:0];
			add_2<= add2[11:8]+add2[7:0];
			add_3<= add3[11:8]+add3[7:0];
			add_4<= add4[11:8]+add4[7:0];
			///////////////////////////////////////
			case(cnt)
 
			0:begin
				add1<= O[2]+V;
				add2<= O[3]+Vx2;
				add3<= O[4]+Vx3;
				add4<= O[5]+Vx3+V;
 
				IS_255_1<= (&O[2] || &V)? 1:0;
				IS_255_2<= (&O[3] || &V)? 1:0;
				IS_255_3<= (&O[4] || &V)? 1:0;
				IS_255_4<= (&O[5] || &V)? 1:0;
			end
 
			1:begin
				add1<= O[6]+Vx2+Vx3;
				add2<= O[7]+Vx6;
				add3<= O[8]+Vx6+V;
				add4<= O[9]+Vx6+Vx2;
 
				IS_255_1<= (&O[6] || &V)? 1:0;
				IS_255_2<= (&O[7] || &V)? 1:0;
				IS_255_3<= (&O[8] || &V)? 1:0;
				IS_255_4<= (&O[9] || &V)? 1:0;
			end
 
			2:begin
				add1<= O[10]+Vx9;
				add2<= O[11]+Vx9+V;
				add3<= O[12]+Vx9+Vx2;
				add4<= O[13]+Vx9+Vx3;
 
				IS_255_1<= (&O[10] || &V)? 1:0;
				IS_255_2<= (&O[11] || &V)? 1:0;
				IS_255_3<= (&O[12] || &V)? 1:0;
				IS_255_4<= (&O[13] || &V)? 1:0;
			end
 
			3:begin
				add1<= O[14]+Vx6+Vx7;
				add2<= O[15]+Vx6+Vx8;
				add3<= O[16]+Vx6+Vx9;
				add4<= 0;
 
				IS_255_1<= (&O[14] || &V)? 1:0;
				IS_255_2<= (&O[15] || &V)? 1:0;
				IS_255_3<= (&O[16] || &V)? 1:0;
				IS_255_4<=  1;
			end
 
			default:begin
				add1<= P[2]+Vx2;
				add2<= P[3]+Vx3+V;
				add3<= P[4]+Vx6;
				add4<= 0;
 
				IS_255_1<= (&P[2] || &V)? 1:0;
				IS_255_2<= (&P[3] || &V)? 1:0;
				IS_255_3<= (&P[4] || &V)? 1:0;
				IS_255_4<= 1;
			end
 
			endcase
			/////////////////////////////////////////////////
			if(cnt>2 && cnt < 7)   //// from 3 to 6
				OV<=OV^dec1^dec2^dec3^dec4;
 
			if(cnt ==7)  // 7
				PV<=PV^dec1^dec2^dec3^dec4;
 
		end
		/////////////////////////////////////////////////////
		//// divide OV/PV and write value in output memory	
		state6:begin  	
			if(cnt == 4)
				begin
					cnt<=0;
					WE_0<=1;
					state<=state4;
				end	
			else
				cnt<=cnt+1;
			///////////////////////////////////////
			div1<=1;
			add_pow1<=OV;
			add_pow2<=PV;
			add_1 <= pow1-pow2;
			IS_255_1_delayed<= (&pow1 || &pow2)? 1:0;
			correction_value<= initial_value ^ dec1;
		end
		///////////////////////////////////////////////////////
		default:begin    //// state7
			state<= state1;
			DONE<=0;
			cnt<=0;
		end
		/////////////////////////////////////////////////////
		endcase
		end
end
 
endmodule 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.