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

Subversion Repositories bch_configurable

[/] [bch_configurable/] [trunk/] [src/] [test_bch_syndrome.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 Success105
///-----------------------------------------
2
///introduce:
3
///bch syndrome generation in decoder
4
///author:jiml
5
///record:
6
///2015.1.31    initial
7
///-----------------------------------------
8
`timescale 1ns/100ps
9
module test_bch_syndrome
10
#(
11
parameter C_DWIDTH = 128,                  //input data width
12
parameter C_COEF_NUM = 43,                 //correct threshold
13
parameter C_PRIMPOLY_ORDER = 14,           //order of eigenpolynomial
14
parameter C_PRIM_POLY = 15'h4443           //eigenpolynomial
15
)
16
(
17
input                                        I_clk        ,
18
input                                        I_rst        ,
19
input      [C_DWIDTH-1:0]                    I_data       ,    //input data
20
input                                        I_data_v     ,    //input data available
21
input                                        I_data_sof   ,    //input data frame start
22
input                                        I_data_eof   ,    //input data frame end
23
output reg [C_COEF_NUM*C_PRIMPOLY_ORDER-1:0] O_syndrome   ,    //syndrome
24
output reg                                   O_syndrome_v      //syndrome available
25
);
26
 
27
//------------------------------------------
28
//parameter and variable
29
//------------------------------------------
30
localparam [C_PRIMPOLY_ORDER*C_PRIMPOLY_ORDER*C_COEF_NUM-1:0] C_TRANS_MATRIX = F_transform(0);
31
localparam C_UPP_WIDTH = GETASIZE(C_PRIMPOLY_ORDER);
32
localparam C_GEN_UPP = F_GEN_NUM(0);
33
localparam C_GEN_POLY = F_GEN_POLY2(0);
34
localparam C_SHIFT_NUM = F_shift_cal(0);
35
 
36
reg [C_PRIMPOLY_ORDER-1:0] S_reg [C_COEF_NUM-1:0];
37
reg S_data_eof = 0;
38
reg [C_DWIDTH-1:0] S_data = 0;
39
reg S_data_eof_d = 0;
40
reg S_data_v = 0;
41
reg S_data_sof = 0;
42
 
43
//--------------------------------------------
44
//function
45
//--------------------------------------------
46
//element generation in Galois Field
47
function [C_PRIMPOLY_ORDER-1:0] F_gen;
48
input [C_PRIMPOLY_ORDER-1:0] S_init;
49
input integer S_times;
50
integer i;
51
begin
52
        F_gen = S_init;
53
    for(i=0;i<S_times;i=i+1)
54
        begin
55
            if(F_gen[C_PRIMPOLY_ORDER-1])
56
                    F_gen = (F_gen<<1) ^ C_PRIM_POLY[C_PRIMPOLY_ORDER-1:0];
57
                else
58
                    F_gen = (F_gen<<1);
59
        end
60
end
61
endfunction
62
 
63
//2*t-1 power of element transform to 1 power of element
64
function [C_PRIMPOLY_ORDER*C_PRIMPOLY_ORDER*C_COEF_NUM-1:0] F_transform;
65
input red;
66
integer i,j,k;
67
reg [C_PRIMPOLY_ORDER-1:0] S_reg;
68
begin
69
        for(i=0;i<C_COEF_NUM;i=i+1)
70
        begin
71
                for(j=0;j<C_PRIMPOLY_ORDER;j=j+1)
72
                begin
73
                    S_reg = F_gen(1,j*(2*i+1));
74
                        for(k=0;k<C_PRIMPOLY_ORDER;k=k+1)
75
                        begin
76
                            F_transform[C_PRIMPOLY_ORDER*C_PRIMPOLY_ORDER*i+C_PRIMPOLY_ORDER*k+j] = S_reg[k];
77
                        end
78
                end
79
        end
80
end
81
endfunction
82
 
83
//when length of encode polynomial is not exactly divided into C_DWIDTH, data should shift right to occupy C_DWIDTH bits fully
84
function integer F_shift_cal;
85
input red;
86
integer i;
87
integer temp;
88
begin
89
        F_shift_cal = 0;
90
        for(i=0;i<C_COEF_NUM;i=i+1)
91
                F_shift_cal=F_shift_cal+C_GEN_UPP[i*C_UPP_WIDTH+:C_UPP_WIDTH];
92
 
93
    while(F_shift_cal>C_DWIDTH)
94
                F_shift_cal = F_shift_cal - C_DWIDTH;
95
        F_shift_cal = C_DWIDTH-F_shift_cal;
96
end
97
endfunction
98
 
99
//generated polynomial cascaded
100
function [C_PRIMPOLY_ORDER*C_COEF_NUM-1:0] F_GEN_POLY2;
101
input red;
102
integer i,j,k;
103
integer pointer;
104
reg [2**C_PRIMPOLY_ORDER-2:0] S_flag;
105
reg [C_PRIMPOLY_ORDER-1:0] S_temp [C_PRIMPOLY_ORDER:0];
106
reg [C_PRIMPOLY_ORDER-1:0] S_temp2;
107
begin
108
        F_GEN_POLY2 = 0;
109
        for(i=0;i<C_PRIMPOLY_ORDER;i=i+1)    //least bits are eigenpolynomial
110
                F_GEN_POLY2[i] = C_PRIM_POLY[i];
111
        for(i=1;i<C_COEF_NUM;i=i+1)          //there are C_COEF_NUM generated polynomial
112
        begin
113
                for(j=1;j<=C_PRIMPOLY_ORDER;j=j+1)
114
                        S_temp[j] = 0;
115
                S_temp[0]=1;
116
                S_flag = 0;
117
            for(j=1;j<=C_PRIMPOLY_ORDER;j=j+1)   //each polynomial have at most C_PRIMPOLY_ORDER element
118
                begin
119
                        pointer = (2*i+1)*(2**(j-1));
120
                        while(pointer>(2**C_PRIMPOLY_ORDER-2))
121
                                pointer = pointer - (2**C_PRIMPOLY_ORDER-1);
122
                    if(!S_flag[pointer])
123
                        begin
124
                            S_flag[pointer] = 1;
125
                                S_temp2 = F_gen(1,pointer);
126
                                for(k=C_PRIMPOLY_ORDER-1;k>0;k=k-1)
127
                                begin
128
                                    S_temp[k]= F_mult(S_temp[k],S_temp2) ^ S_temp[k-1];
129
                                end
130
                                S_temp[0] = F_mult(S_temp[0],S_temp2);
131
                                S_temp[C_PRIMPOLY_ORDER] = S_temp[C_PRIMPOLY_ORDER-1];
132
                        end
133
                end
134
                for(j=0;j<C_PRIMPOLY_ORDER;j=j+1)
135
                        F_GEN_POLY2[i*C_PRIMPOLY_ORDER+j] = (S_temp[j] == 1);
136
        end
137
end
138
endfunction
139
 
140
//polynomial multiplication in Galois Field
141
function [C_PRIMPOLY_ORDER-1:0] F_mult;
142
input [C_PRIMPOLY_ORDER-1:0] S_data1;
143
input [C_PRIMPOLY_ORDER-1:0] S_data2;
144
reg [C_PRIMPOLY_ORDER*2-1:0] S_temp;
145
integer i;
146
begin
147
    S_temp = 0;
148
        F_mult = 0;
149
        for(i=0;i<C_PRIMPOLY_ORDER;i=i+1)
150
        begin
151
            S_temp = S_temp ^ ({(C_PRIMPOLY_ORDER*2){S_data1[i]}} & (S_data2<<i));
152
        end
153
        for(i=0;i<C_PRIMPOLY_ORDER*2;i=i+1)
154
        begin
155
                F_mult = {F_mult[C_PRIMPOLY_ORDER-2:0],S_temp[C_PRIMPOLY_ORDER*2-1-i]} ^ (C_PRIM_POLY[C_PRIMPOLY_ORDER-1:0] & {C_PRIMPOLY_ORDER{F_mult[C_PRIMPOLY_ORDER-1]}});
156
        end
157
end
158
endfunction
159
 
160
//width calculation
161
function integer GETASIZE;
162
input integer a;
163
integer i;
164
begin
165
    for(i=1;(2**i)<=a;i=i+1)
166
      begin
167
      end
168
    GETASIZE = i;
169
end
170
endfunction
171
 
172
//length of generated polynomial cascaded
173
function [C_UPP_WIDTH*C_COEF_NUM-1:0] F_GEN_NUM;
174
input red;
175
integer i,j;
176
integer temp;
177
reg [2**C_PRIMPOLY_ORDER-2:0] S_flag;
178
begin
179
        F_GEN_NUM = 0;
180
    for(i=0;i<C_COEF_NUM;i=i+1)
181
        begin
182
                S_flag = 0;
183
                for(j=1;j<=C_PRIMPOLY_ORDER;j=j+1)
184
                begin
185
                        temp = (2*i+1)*(2**(j-1));
186
                        while(temp > 2**C_PRIMPOLY_ORDER-2)
187
                                temp = temp - (2**C_PRIMPOLY_ORDER-1);
188
                    if(!S_flag[temp])
189
                        begin
190
                            S_flag[temp] = 1;
191
                                F_GEN_NUM[i*C_UPP_WIDTH+:C_UPP_WIDTH]=F_GEN_NUM[i*C_UPP_WIDTH+:C_UPP_WIDTH]+'d1;
192
                        end
193
                end
194
        end
195
end
196
endfunction
197
 
198
//polynomial division in Galois Field
199
function [C_PRIMPOLY_ORDER-1:0] F_reg_update;
200
input [C_PRIMPOLY_ORDER-1:0] S_reg_ori;
201
input [C_DWIDTH-1:0] S_data;
202
input [C_PRIMPOLY_ORDER-1:0] S_poly;
203
input integer S_upp;
204
integer i;
205
reg S_temp1;
206
reg S_temp2;
207
begin
208
        F_reg_update = S_reg_ori;
209
        for(i=0;i<C_DWIDTH;i=i+1)
210
        begin
211
                S_temp1 = F_reg_update[S_upp];
212
                S_temp2 = S_temp1 ^ S_data[C_DWIDTH-1-i];
213
                F_reg_update[C_PRIMPOLY_ORDER-1:1] = {F_reg_update[C_PRIMPOLY_ORDER-2:0]} ^ ({(C_PRIMPOLY_ORDER-1){S_temp1}} & S_poly[C_PRIMPOLY_ORDER-1:1]);
214
                F_reg_update[0] = S_temp2;
215
        end
216
end
217
endfunction
218
 
219
//---------------------------------------
220
//syndrome calculation
221
//---------------------------------------
222
genvar S_i;
223
generate
224
for(S_i=0;S_i<C_COEF_NUM;S_i=S_i+1)   //parallel calculation
225
begin:test
226
 
227
wire [C_PRIMPOLY_ORDER-1:0] S_para1;
228
reg [C_DWIDTH-1:0] S_para2;
229
 
230
localparam C_POLY = C_GEN_POLY[S_i*C_PRIMPOLY_ORDER+:C_PRIMPOLY_ORDER];
231
localparam C_UPP = C_GEN_UPP[S_i*C_UPP_WIDTH+:C_UPP_WIDTH]-1;
232
 
233
always @(posedge I_clk)
234
begin
235
        S_para2 <= (C_SHIFT_NUM != 0) ? (I_data_sof ? {{C_SHIFT_NUM{1'b0}},I_data[C_DWIDTH-1-:(C_DWIDTH-C_SHIFT_NUM)]} : {S_data,I_data[C_DWIDTH-1-:(C_DWIDTH-C_SHIFT_NUM)]}) : I_data;
236
end
237
 
238
assign S_para1 = S_data_sof ? 'd0 : S_reg[S_i];
239
 
240
always @(posedge I_clk)
241
begin
242
    if(S_data_v)
243
        begin
244
                S_reg[S_i] <= F_reg_update(S_para1,S_para2,C_POLY,C_UPP);
245
        end
246
end
247
 
248
end
249
endgenerate
250
 
251
always @(posedge I_clk)
252
begin
253
    S_data <= I_data;
254
end
255
 
256
integer j,k;
257
always @(posedge I_clk)
258
begin
259
        S_data_eof <= I_data_eof;
260
        S_data_eof_d <= S_data_eof;
261
    O_syndrome_v <= S_data_eof_d;
262
        S_data_v <= I_data_v;
263
        S_data_sof <= I_data_sof;
264
        if(S_data_eof_d)
265
        begin
266
            for(j=0;j<C_COEF_NUM;j=j+1)
267
                        for(k=0;k<C_PRIMPOLY_ORDER;k=k+1)
268
                        begin
269
                            O_syndrome[j*C_PRIMPOLY_ORDER+k] <= ^(S_reg[j] & C_TRANS_MATRIX[j*C_PRIMPOLY_ORDER*C_PRIMPOLY_ORDER+k*C_PRIMPOLY_ORDER+:C_PRIMPOLY_ORDER]);
270
                        end
271
        end
272
end
273
 
274
 
275
endmodule

powered by: WebSVN 2.1.0

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