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

Subversion Repositories reed_solomon_decoder

[/] [reed_solomon_decoder/] [trunk/] [rtl/] [lamda_roots.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
 
*/
 
 
/// this block is used to calculate lamda polynomial roots
module lamda_roots
(
// active high flag for one clock edge to indicate that lamda polynomial coeff is ready
input CE,  
input clk, // input clock planned to be 56 Mhz
input reset, // active high asynchronous reset
input [7:0] Lc0,Lc1,Lc2,Lc3,Lc4,Lc5,Lc6,Lc7,Lc8, /// input coeff of lamda polynomial
 
output reg [7:0] add_GF_ascending,   // output address to GF_ascending_rom
output reg[7:0] add_GF_dec0,add_GF_dec1,add_GF_dec2, // output address to GF_dec_rom
 
input [7:0] power,  // input power value from GF_ascending_rom
input [7:0] decimal0,decimal1,decimal2, // input decimal value of GF_dec_rom
 
 // output active high flag to indicate that all roots is ready (for one clock)
output reg CEO,
output reg [3:0] root_cnt, ///  up to 8
// output roots of lamda polynomial up to 8 roots
output reg [7:0] r1,r2,r3,r4,r5,r6,r7,r8 
);
 
 
reg one,two; //states
/// decimal value & power value of possible values of roots 0---255
reg [7:0] V,Vp;  
reg [3:0] cnt9;
reg [1:0] cnt3;
 
reg [11:0] add0,add1,add2;
reg [8:0] Vx2;
reg [9:0] Vx3;
reg [10:0] Vx6;
reg [7:0] X0,X1,X2,X3;   /// xor values
reg [7:0] GF1,GF2,GF3,GF4; /// decimal GF values
reg [7:0] GF5,GF6,GF7,GF8; /// decimal GF values
reg [8:0] add_GF_dec0_reg,add_GF_dec1_reg,add_GF_dec2_reg;
reg [7:0] add_GF_dec0_reg0,add_GF_dec1_reg0,add_GF_dec2_reg0;
reg F0,F1,F2;   /// IS 255
reg FF0,FF1,FF2; /// IS 255 delayed one clock
reg FFF0,FFF1,FFF2; /// IS 255  delayed two clocks
reg [7:0] L0,L1,L2,L3,L4,L5,L6,L7,L8; /// Lamda coeff
reg yes,E;
reg chk_flag; 
reg [1:0] chk_cnt;
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
/////////////////// values generator (0--255  every three clocks)
always@(posedge clk or posedge reset)
begin
	if (reset)
		begin
			cnt3<=2;
			V<=8'd255;
		end
	else
		begin
			if(two)
				begin
					if (cnt3 ==2)
						begin
							cnt3<=0;
							V<=V+1;
						end
					else	
						cnt3<=cnt3+1;
				end
			else
				begin
					cnt3<=2;
					V<=8'd255;
				end
		end
end
 
 
 
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////// main process
always@(posedge clk or posedge reset)
begin
	if (reset)
		begin
			one<=0;
			two<=0;
			cnt9<=0;
			L0<=0;L1<=0;L2<=0;L3<=0;L4<=0;
			L5<=0;L6<=0;L7<=0;L8<=0;
			add_GF_dec0_reg<=0;add_GF_dec1_reg<=0;add_GF_dec2_reg<=0;
			add_GF_dec0_reg0<=0;add_GF_dec1_reg0<=0;add_GF_dec2_reg0<=0;
			F0<=0;F1<=0;F2<=0;
			FF0<=0;FF1<=0;FF2<=0;
			FFF0<=0;FFF1<=0;FFF2<=0;
			add0<=0;add1<=0;add2<=0;
			Vx2<=0;Vx3<=0;Vx6<=0;Vp<=0;
			X0<=0;X1<=0;X2<=0;X3<=0;
			GF1<=0;GF2<=0;GF3<=0;GF4<=0;
			GF5<=0;GF6<=0;GF7<=0;GF8<=0;
			yes<=0;
			E<=0;
			chk_flag<=0; chk_cnt<=0;
			////////////////outputs///////////////////////
			root_cnt<=0;
			CEO<=0;
			r1<=0;r2<=0;r3<=0;r4<=0;
			r5<=0;r6<=0;r7<=0;r8<=0;
			add_GF_dec0<=0;add_GF_dec1<=0;add_GF_dec2<=0;
			add_GF_ascending<=0;
		end
	else
		begin
			if(CE)
				begin
					one<=1;
					L0<=Lc0; // no need to convert it to power form
					add_GF_ascending<=Lc1;
					L2<=Lc2;L3<=Lc3;L4<=Lc4;
					L5<=Lc5;L6<=Lc6;L7<=Lc7;L8<=Lc8;
					cnt9<=7;
				end
			////// state one////////////////////////////////////////////////	
			if(one)
				begin
					cnt9<=cnt9-1;
					/////////////////////////////////
					case(cnt9)
					7: begin add_GF_ascending<=L2; end
					6: begin add_GF_ascending<=L3; L1<=power; end
					5: begin add_GF_ascending<=L4; L2<=power; end
					4: begin add_GF_ascending<=L5; L3<=power; end
					3: begin add_GF_ascending<=L6; L4<=power; end
					2: begin add_GF_ascending<=L7; L5<=power; end
					1: begin add_GF_ascending<=L8; L6<=power; end
					0: begin  L7<=power;  end
					15:begin 
							L8<=power;  one<=0; two<=1; root_cnt<=0;
							/// to avoid false roots from xor operations
							X0<=8'h55;X1<=8'hAA;X2<=8'hF1;X3<=8'h55;
							GF1<=0;GF2<=0;GF3<=0;GF4<=0;
							GF5<=0;GF6<=0;GF7<=0;GF8<=0;
							r1<=0;r2<=0;r3<=0;r4<=0;
							r5<=0;r6<=0;r7<=0;r8<=0;
							chk_flag<=0; chk_cnt<=0;
						end
					default: begin   add_GF_ascending<=L2;       end   /// just for default case
					endcase
					//////////////////////////////////
				end	
			////// state two////////////////////////////////////
			if(two)
				begin
					///////////////Delay level one ////////////////////
					if(cnt3 == 0)
						begin
							add_GF_ascending<=V;
						end
					//////////////////////////////////////////////////////
					///////////////////////////Delay level  two//////////
					Vp <=power;
					////////////////////////////////////////////////////////
					///////////////////////////Delay level  three//////////
					 case (cnt3)  
					 0:
						 begin
							 add0<=L1+Vp;
							 add1<=L2+Vp+Vp;
							 add2<=0;
							 F0<= (&L1 || &Vp);
							 F1<=(&L2 || &Vp);
							 F2<=0;
						 end
					1:
						 begin
							 add0<=L3+Vx3;
							 add1<=L4+Vx3+Vp;
							 add2<=L5+Vx3+Vx2;
							 F0<= (&L3 || &Vp);
							 F1<=(&L4 || &Vp);
							 F2<=(&L5 || &Vp);
						 end
					2:
						 begin
							 add0<=L6+Vx6;
							 add1<=L7+Vx6+Vp;
							 add2<=L8+Vx6+Vx2;
							 F0<= (&L6 || &Vp);
							 F1<=(&L7|| &Vp);
							 F2<=(&L8 || &Vp);
						 end
					default:
						 begin /// using first case values for default
							 add0<=L1+Vp;
							 add1<=L2+Vp+Vp;
							 add2<=0;
							 F0<= (&L1 || &Vp);
							 F1<=(&L2 || &Vp);
							 F2<=0;
						 end	 
					 endcase
					 //// Vp constant for 3 clocks so these operations can  
					 /////be done without using operation switcher cnt3
					 Vx2<=Vp+Vp;
					 Vx3<=Vp+Vp+Vp;
					 Vx6<=Vx3+Vx3;
 
					 ////////////////////////////////////////////////////
					///////////////////////////Delay level  four/////////
					 /// 8 + 4 ===> need 9 bits
					add_GF_dec0_reg<=add0[11:8] + add0[7:0];   
					add_GF_dec1_reg<=add1[11:8] + add1[7:0];
					add_GF_dec2_reg<=add2[11:8] + add2[7:0];
 
					 FF0<=F0; FF1<=F1; FF2<=F2;
					 ///////////////////////////////////////////////////
					///////////////////////////Delay level  five///////
					 ///   9 bits  =====> 8 bits
					add_GF_dec0_reg0<=add_GF_dec0_reg[8] + add_GF_dec0_reg[7:0];  
					add_GF_dec1_reg0<=add_GF_dec1_reg[8] + add_GF_dec1_reg[7:0];
					add_GF_dec2_reg0<=add_GF_dec2_reg[8] + add_GF_dec2_reg[7:0];
 
					 FFF0<=FF0; FFF1<=FF1; FFF2<=FF2;
					//////////////////////////////////////////////////////////
					///////////////////////////Delay level  six/////////////
					 add_GF_dec0 <= (FFF0)?  8'h00 : (&add_GF_dec0_reg0)? 8'h01:add_GF_dec0_reg0+1;
					 add_GF_dec1 <= (FFF1)?  8'h00 : (&add_GF_dec1_reg0)? 8'h01:add_GF_dec1_reg0+1;
					 add_GF_dec2 <= (FFF2)?  8'h00 : (&add_GF_dec2_reg0)? 8'h01:add_GF_dec2_reg0+1;
					 ////////////////////////////////////////////////////////
					///////////////////////////Delay level  seven///////////
					X0<=L0;
					GF1<=decimal0;
					GF2<=decimal1;
					///////////////////////////////////////////////////////
					///////////////////////////Delay level  eight/////////
					X1<=X0 ^ GF1^GF2;
					GF3<=decimal0;
					GF4<=decimal1;
					GF5<=decimal2;
					//////////////////////////////////////////////////////
					///////////////////////////Delay level  nine/////////
					X2<=X1 ^ GF3^GF4^GF5;
					GF6<=decimal0;
					GF7<=decimal1;
					GF8<=decimal2;
					/////////////////////////////////////////////////////
					///////////////////////////Delay level  ten/////////
					X3<=X2 ^ GF6^GF7^GF8;
					////////////////////////////////////////////////////
					///////////////////////////Delay level  eleven//////
					if (X3==0  && chk_flag && cnt3==0)
						begin
							root_cnt<=root_cnt+1;
							yes<=1;
						end
					/////////////////////////////////////////////////////
					///////////////////////////Delay level  twelve//////
					if(yes)
						begin
							yes<=0;
							case(root_cnt)
							1: begin r1<=V-8'd4; end
							2: begin r2<=V-8'd4; end
							3: begin r3<=V-8'd4; end
							4: begin r4<=V-8'd4; end
							5: begin r5<=V-8'd4; end
							6: begin r6<=V-8'd4; end
							7: begin r7<=V-8'd4; end
							default: begin r8<=V-8'd4; end
							endcase
						end
					//////////////////////////////////////////////////
					///////////////////////////Delay level  thirteen//
					if(&(V-8'd4)  &&  E  && cnt3 == 1)   
					// when value == 255+delay , we now scanned all possible values of roots 
						begin
							two<=0;
							CEO<=1;
							E<=0;
						end
 
					if(&V && cnt3==0)  
					// when value == 255 and cnt3 ==0 so 255 value entered state two
						E<=1;
					////////////////////////////////////////////////////
					/////////////////////chk_flag generation part//////
					/////to control the check of X3 (xor out value) only with right places .
					if(cnt3 == 0)
						begin
							if(&chk_cnt)
								begin
									chk_cnt<= 2'd3;
									chk_flag<=1;
								end
							else
								chk_cnt<=chk_cnt+1;
						end
				end
			///////////////////////////////////////////////
			if (CEO)
				CEO<=0; /// to make it active for one clock
		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.