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

Subversion Repositories bch_configurable

[/] [bch_configurable/] [trunk/] [src/] [test_bch_bm.v] - Rev 3

Go to most recent revision | Compare with Previous | Blame | View Log

///-----------------------------------------
///introduce:
///bch error position polynomial calculate by bm algorithm
///author:jiml
///record:
///2015.1.31    initial
///2015.2.2     S_syndrome modified from parallel to serial
///-----------------------------------------
`timescale 1ns/100ps
module test_bch_bm
#(
    parameter C_PRIMPOLY_ORDER = 14,          //order of eigenpolynomial
    parameter C_COEF_NUM = 43,                //correct threshold
	parameter C_PRIMPOLY = 15'h4443           //eigenpolynomial
)
(
input                                                           I_clk        ,
input                                                           I_rst        ,
input      [C_PRIMPOLY_ORDER*C_COEF_NUM-1:0]                    I_syndrome   , //syndrome cascaded
input                                                           I_syndrome_v , //syndrome available
output reg [C_PRIMPOLY_ORDER*C_COEF_NUM-1+C_PRIMPOLY_ORDER:0]   O_err_pos    , //error position polynomial
(* MAX_FANOUT=30 *)output reg                                   O_err_pos_v    //error position polynomial available
);
 
//--------------------------------
//parameter and variable
//--------------------------------
localparam C_CYCLE = GETASIZE(C_COEF_NUM);
integer i,j,jj;
reg [C_CYCLE+1:0]                             S_syndrome_v_slr = 0;
reg                                           S_syndrome_v_all = 0;
reg [C_PRIMPOLY_ORDER-1:0]                    S_syndrome [2*C_COEF_NUM-1:0];
reg                                           S_syndrome_v = 0;
reg                                           S_syndrome_v_d = 0;
reg                                           S_syndrome_v_2d = 0;
reg                                           S_syndrome_v_3d = 0;
reg                                           S_bm_cnt2_d = 0;
reg [C_PRIMPOLY_ORDER*C_COEF_NUM-1:0]         S_syndrome_seq = 0;
reg [C_PRIMPOLY_ORDER*C_COEF_NUM-1:0]         S_syndrome_seq2 = 0;
reg [C_PRIMPOLY_ORDER-1:0]                    S_syndrome_new = 0;
reg [C_PRIMPOLY_ORDER-1:0]                    S_syndrome_seq_sel = 0;
reg [C_PRIMPOLY_ORDER-1:0]                    S_syndrome_new_d = 0;
reg [C_PRIMPOLY_ORDER*(C_COEF_NUM+1)-1:0]     S_syndrome_slr = 0;
(* MAX_FANOUT=8 *)reg [C_PRIMPOLY_ORDER-1:0]  S_poly_v [C_COEF_NUM-1+1:0];
reg [C_PRIMPOLY_ORDER-1:0]                    S_poly_deltav [C_COEF_NUM-1+1:0];
(* MAX_FANOUT=16 *)reg [C_PRIMPOLY_ORDER-1:0] S_poly_k [C_COEF_NUM-1+2:0];
(* MAX_FANOUT=50 *)reg [C_PRIMPOLY_ORDER-1:0] S_delta;
reg [C_PRIMPOLY_ORDER-1:0]                    S_d_uint [C_COEF_NUM-1+1:0];
(* MAX_FANOUT=36 *)reg [C_PRIMPOLY_ORDER-1:0] S_d;
wire [C_PRIMPOLY_ORDER-1:0]                   S_d_xor [C_COEF_NUM+1:0];
reg [C_PRIMPOLY_ORDER-1:0]                    S_mult_result [C_COEF_NUM-1:0];
reg                                           S_bm_v = 0;
reg                                           S_bm_v_d = 0;
reg                                           S_bm_v_2d = 0;
(* MAX_FANOUT=36 *)reg [1:0]                  S_bm_cnt = 0;
reg [C_CYCLE-1:0]                             S_bm_cnt2 = 0;
reg                                           S_d_nozero = 0;
reg                                           S_kdelta_v = 0;
reg [C_COEF_NUM-1:0]                          S_poly_v_exist = 0;
reg                                           S_poly_v_exist_all = 0;
reg                                           S_syndrome_ram_we = 0;
reg [C_PRIMPOLY_ORDER-1:0]                    S_syndrome_ram [2**C_CYCLE-1:0];
reg [C_CYCLE-1:0]                             S_syndrome_waddr = 0;
reg [C_CYCLE-1:0]                             S_syndrome_raddr = 0;
reg [C_PRIMPOLY_ORDER-1:0]                    S_syndrome_ram_dout = 0;
reg                                           S_k_v = 0;
 
 
///----------------------------
///function
///----------------------------
//width calculation
function integer GETASIZE;
input integer a;
integer i;
begin
    for(i=1;(2**i)<=a;i=i+1)
      begin
      end
    GETASIZE = i;
end
endfunction
 
//two elements in Galois Field multiplication
function [C_PRIMPOLY_ORDER-1:0] F_var_upgrade;
input [C_PRIMPOLY_ORDER-1:0] S_mult1;
input [C_PRIMPOLY_ORDER-1:0] S_mult2;
integer i;
reg [C_PRIMPOLY_ORDER-1:0] S_temp1;
reg [C_PRIMPOLY_ORDER-1:0] S_temp2;
begin
	F_var_upgrade = {C_PRIMPOLY_ORDER{1'b0}};
	for(i=0;i<C_PRIMPOLY_ORDER;i=i+1)
	begin
	    S_temp1 = {C_PRIMPOLY_ORDER{F_var_upgrade[C_PRIMPOLY_ORDER-1]}} & C_PRIMPOLY[C_PRIMPOLY_ORDER-1:0];
		S_temp2 = {C_PRIMPOLY_ORDER{S_mult1[C_PRIMPOLY_ORDER-1-i]}} & S_mult2;
		F_var_upgrade = {F_var_upgrade[C_PRIMPOLY_ORDER-2:0],1'b0} ^ S_temp1 ^ S_temp2;
	end
end
endfunction
 
///----------------------------
///syndrome
///----------------------------
always @(posedge I_clk)
begin
    S_syndrome_v_slr <= {S_syndrome_v_slr[C_CYCLE:0],I_syndrome_v};
	S_syndrome_v_all <= |S_syndrome_v_slr;
	S_syndrome_v <= I_syndrome_v;
	S_syndrome_v_d <= S_syndrome_v;
	S_syndrome_v_2d <= S_syndrome_v_d;
	S_syndrome_v_3d <= S_syndrome_v_2d;
	S_bm_cnt2_d <= S_bm_cnt2[0];
end
 
//an odd order syndrome used to calculate even order syndrome
always @(posedge I_clk)
begin
    if(I_syndrome_v)
	    S_syndrome_seq <= I_syndrome;
	else if((S_bm_cnt == 'd2 && S_bm_cnt2_d) || S_syndrome_v)
	    S_syndrome_seq <= S_syndrome_seq>>C_PRIMPOLY_ORDER;
end
 
//every iteration need an odd order syndrome
always @(posedge I_clk)
begin
    if(I_syndrome_v)
	    S_syndrome_seq2 <= I_syndrome;
	else if(S_bm_cnt == 'd1)
	    S_syndrome_seq2 <= S_syndrome_seq2>>C_PRIMPOLY_ORDER;
end
 
//even order syndrome generation by multiplication, multiplier is odd order or even order 
always @(posedge I_clk) 
begin
    S_syndrome_new <= F_var_upgrade(S_syndrome_seq_sel,S_syndrome_seq_sel);
end
 
//multiplier selection, S_syndrome_seq[C_PRIMPOLY_ORDER-1:0] is odd order, and S_syndrome_ram_dout is even order
always @(posedge I_clk)
begin
    if(I_syndrome_v)
	    S_syndrome_seq_sel <= I_syndrome[C_PRIMPOLY_ORDER-1:0];
	else if(S_syndrome_v_3d)
	    S_syndrome_seq_sel <= S_syndrome_new_d;
	else if(S_bm_cnt == 'd2) 
	begin
	    S_syndrome_seq_sel <= (S_bm_cnt2_d) ? S_syndrome_seq[C_PRIMPOLY_ORDER-1:0] : S_syndrome_ram_dout;
	end
end
 
//every iteration need an even order syndrome
always @(posedge I_clk) 
begin
    if(S_bm_cnt == 'd1 || S_syndrome_v_d)
	    S_syndrome_new_d <= S_syndrome_new;
end
 
//even order syndrome are saved into ram for further even order syndrome calculation
always @(posedge I_clk)
begin
    S_syndrome_ram_we <= (S_bm_cnt == 'd1) && S_bm_v_2d;
	if(S_syndrome_ram_we)
	    S_syndrome_ram[S_syndrome_waddr] <= S_syndrome_new_d;
	if(I_syndrome_v)
	    S_syndrome_waddr <= 'd0;
	else if(S_syndrome_ram_we)
	    S_syndrome_waddr <= S_syndrome_waddr + 'd1;
	S_syndrome_ram_dout <= S_syndrome_ram[S_syndrome_raddr];
	if(I_syndrome_v)
	    S_syndrome_raddr <= 'd0;
	else if((S_bm_cnt == 'd1) && (!S_bm_cnt2_d) && S_bm_v_2d)
	    S_syndrome_raddr <= S_syndrome_raddr + 'd1;
end
 
//syndrome update every iteration
always @(posedge I_clk)
begin
    if(I_syndrome_v)
	begin
	    S_syndrome_slr <= 'd0;
		S_syndrome_slr[C_PRIMPOLY_ORDER-1:0] <= I_syndrome[C_PRIMPOLY_ORDER-1:0];
		S_syndrome_slr[2*C_PRIMPOLY_ORDER-1:C_PRIMPOLY_ORDER] <= 'd1;
	end
	else if(S_bm_cnt == 'd2)
	begin
	    S_syndrome_slr <= S_syndrome_slr<<(C_PRIMPOLY_ORDER*2);
		S_syndrome_slr[0+:C_PRIMPOLY_ORDER*2] <= {S_syndrome_new_d,S_syndrome_seq2[C_PRIMPOLY_ORDER-1:0]};
	end
end
 
///-------------------------------
///bm
///-------------------------------
///bm algorithm
///v(0)=1,k(0)=1,delta(-2)=1
///for k=0:1:C_COEF_NUM-1
///v(2k+2)=delta(2k-2)*v(2k)+d(2k)*k(2k)*z
///k(2k+2)=z^2*k(2k)        if d(2k) == 0 or if deg v(2k)>k
///k(2k+2)=z*v(2k)          if d(2k) != 0 and if deg v(2k)<=k
///delta(2k)=delta(2k-2)    if d(2k) == 0 or if deg v(2k)>k
///delta(2k)=d(2k)          if d(2k) != 0 and if deg v(2k)<=k
 
always @(posedge I_clk)
begin
    if(S_syndrome_v)
	    S_bm_v <= 'b1;
	else if(S_bm_cnt2 == C_COEF_NUM)
	    S_bm_v <= 'b0;
end
 
always @(posedge I_clk)
begin
    O_err_pos_v <= (!S_bm_v) && S_bm_v_d;
end
 
always @(posedge I_clk)
begin
    if(S_bm_v)
	begin
	    if(S_bm_cnt=='d2)
		    S_bm_cnt <= 'd0;
		else
		    S_bm_cnt <= S_bm_cnt + 'd1;
	end
	else
	    S_bm_cnt <= 'd0;
end
 
always @(posedge I_clk)
begin
    if(S_bm_v)
	begin
	    if(S_bm_cnt=='d1)
		    S_bm_cnt2 <= S_bm_cnt2 + 'd1;
	end
	else
	    S_bm_cnt2 <= 'd0; 
end
 
//variable d generation
always @(posedge I_clk)
begin
	if(S_bm_cnt[1:0]=='d1)
	    S_d <= S_d_xor[C_COEF_NUM+1];	
end
 
always @(posedge I_clk)
begin
    S_d_nozero <= (S_d != 'd0);
	S_kdelta_v <= (S_bm_cnt[1:0]=='d2);
	S_k_v <= (S_bm_cnt[1:0]=='d1);
	S_bm_v_d <= S_bm_v;
	S_bm_v_2d <= S_bm_v_d;
	if(S_bm_cnt[1:0]=='d1)
		S_poly_deltav[C_COEF_NUM] <= F_var_upgrade(S_delta,S_poly_v[C_COEF_NUM]);
end
 
assign S_d_xor[0] = 0;
 
genvar S_jj;
generate
for(S_jj=0;S_jj<=C_COEF_NUM;S_jj=S_jj+1)
begin:bm2
 
assign S_d_xor[S_jj+1] = S_d_xor[S_jj] ^ S_d_uint[S_jj];
 
always @(posedge I_clk)
begin
    if(S_bm_cnt[1:0]=='d0) 
	begin
	    S_d_uint[S_jj] <= F_var_upgrade(S_syndrome_slr[S_jj*C_PRIMPOLY_ORDER+:C_PRIMPOLY_ORDER],S_poly_v[S_jj]);
	end	
end
end
endgenerate
 
 
genvar S_j;
generate
for(S_j=0;S_j<C_COEF_NUM;S_j=S_j+1)
begin:bm
 
always @(posedge I_clk)
begin
    if(S_bm_cnt[1:0]=='d1)
		S_poly_deltav[S_j] <= F_var_upgrade(S_delta,S_poly_v[S_j]);
end
 
//variable v generation
always @(posedge I_clk)
begin
    if(I_syndrome_v)
	    S_poly_v[S_j+1] <= 'd0;
	else if(S_bm_cnt[1:0]=='d2)
	    S_poly_v[S_j+1] <= S_poly_deltav[S_j+1] ^ F_var_upgrade(S_poly_k[S_j],S_d);
end
 
always @(posedge I_clk)
begin
    S_poly_v_exist[S_j] <= (S_poly_v[S_j] != 'd0) && (S_j > S_bm_cnt2);
end
 
always @(posedge I_clk)
begin
    O_err_pos[C_PRIMPOLY_ORDER*S_j+C_PRIMPOLY_ORDER-1-:C_PRIMPOLY_ORDER] <= S_poly_v[S_j];
end
 
end
endgenerate
 
always @(posedge I_clk)
begin
    S_poly_v_exist_all <= |S_poly_v_exist;
	O_err_pos[C_PRIMPOLY_ORDER*C_COEF_NUM+C_PRIMPOLY_ORDER-1-:C_PRIMPOLY_ORDER] <= S_poly_v[C_COEF_NUM];
end
 
always @(posedge I_clk) 
begin
    if(I_syndrome_v)
	    S_poly_v[0] <= 'd1;
	else if(S_bm_cnt[1:0]=='d2)
	    S_poly_v[0] <= S_poly_deltav[0];
end
 
//variable k generation
genvar S_k;
generate
for(S_k=1;S_k<C_COEF_NUM;S_k=S_k+1)
begin:think
always @(posedge I_clk)
begin
    if(I_syndrome_v)
	    S_poly_k[S_k+1] <= 'd0;
	else if(S_k_v)
	begin
	    if(!((S_d != 'd0) && !S_poly_v_exist_all))
		    S_poly_k[S_k+1] <= S_poly_k[S_k-1];
		else
		    S_poly_k[S_k+1] <= S_poly_v[S_k];
	end
end
end
endgenerate
 
always @(posedge I_clk) 
begin
    if(I_syndrome_v)
	begin
	    S_poly_k[0] <= 'd1;
		S_poly_k[1] <= 'd0;
		S_poly_k[C_COEF_NUM+1] <= 'd0;
	end
	else if(S_k_v)
	begin
	    if(!((S_d != 'd0) && !S_poly_v_exist_all))
		begin
		    S_poly_k[0] <= 'd0;
			S_poly_k[1] <= 'd0;
			S_poly_k[C_COEF_NUM+1] <= S_poly_k[C_COEF_NUM-1];
		end
		else
		begin
		    S_poly_k[1] <= S_poly_v[0];
			S_poly_k[0] <= 'd0;
			S_poly_k[C_COEF_NUM+1] <= S_poly_v[C_COEF_NUM];
		end
	end
end
 
//variable delta generation
always @(posedge I_clk) 
begin
    if(I_syndrome_v)
	    S_delta <= 'd1;
	else if(S_kdelta_v && S_d_nozero && !S_poly_v_exist_all)
	    S_delta <= S_d;
end
 
endmodule
 

Go to most recent revision | 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.