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

Subversion Repositories bch_configurable

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 Success105
///-----------------------------------------
2
///introduce:
3
///bch encoder
4
///author:jiml
5
///record:
6
///2015.1.31    initial
7
///-----------------------------------------
8
`timescale 1ns/100ps
9
module test_bch_encode
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_DWIDTH-1:0] O_data      ,  //output data
24
output reg                O_data_v    ,  //output data available
25
output reg                O_data_sof  ,  //output data frame start
26
output reg                O_data_eof     //output data frame end
27
);
28
 
29
///----------------------------------------
30
///parameter and variable
31
///----------------------------------------
32
localparam C_REG_LEN = C_COEF_NUM*C_PRIMPOLY_ORDER;
33
localparam C_GEN_WIDTH = F_TOTAL_NUM(0);
34
localparam C_ECC_PERIOD = F_DIV(C_GEN_WIDTH,C_DWIDTH);
35
localparam C_CNT_WIDTH = GETASIZE(C_ECC_PERIOD);
36
localparam C_GENPOLY = F_GEN_POLY(0);
37
 
38
reg [C_GEN_WIDTH-1:0] S_reg = 0;
39
reg [C_CNT_WIDTH-1:0] S_ecc_cnt = 0;
40
reg S_ecc_v = 0;
41
 
42
//---------------------------------------------
43
//function
44
//---------------------------------------------
45
//calculate length of encode polynomial
46
function integer F_TOTAL_NUM;
47
input red;
48
integer i,j;
49
integer temp;
50
reg [2**C_PRIMPOLY_ORDER-2:0] S_flag;
51
begin
52
        F_TOTAL_NUM = 0;
53
    for(i=0;i<C_COEF_NUM;i=i+1)
54
        begin
55
                S_flag = 0;
56
                for(j=1;j<=C_PRIMPOLY_ORDER;j=j+1)
57
                begin
58
                        temp = (2*i+1)*(2**(j-1));
59
                        while(temp > 2**C_PRIMPOLY_ORDER-2)
60
                                temp = temp - (2**C_PRIMPOLY_ORDER-1);
61
                    if(!S_flag[temp])
62
                        begin
63
                            S_flag[temp] = 1;
64
                                F_TOTAL_NUM=F_TOTAL_NUM+1;
65
                        end
66
                end
67
        end
68
end
69
endfunction
70
 
71
//integer division
72
function integer F_DIV;
73
input integer S_DIVIDEND;
74
input integer S_DIVIDER;
75
begin
76
    F_DIV = (S_DIVIDEND-1)/S_DIVIDER;
77
end
78
endfunction
79
 
80
//polynomial multiplication in Galois Field
81
function [C_PRIMPOLY_ORDER-1:0] F_mult;
82
input [C_PRIMPOLY_ORDER-1:0] S_data1;
83
input [C_PRIMPOLY_ORDER-1:0] S_data2;
84
reg [C_PRIMPOLY_ORDER*2-1:0] S_temp;
85
integer i;
86
begin
87
    S_temp = 0;
88
        F_mult = 0;
89
        for(i=0;i<C_PRIMPOLY_ORDER;i=i+1)
90
        begin
91
            S_temp = S_temp ^ ({(C_PRIMPOLY_ORDER*2){S_data1[i]}} & (S_data2<<i));
92
        end
93
        for(i=0;i<C_PRIMPOLY_ORDER*2;i=i+1)
94
        begin
95
                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]}});
96
        end
97
end
98
endfunction
99
 
100
//element generation in Galois Field
101
function [C_PRIMPOLY_ORDER-1:0] F_gen;
102
input [C_PRIMPOLY_ORDER-1:0] S_init;
103
input integer S_times;
104
integer i;
105
begin
106
        F_gen = S_init;
107
    for(i=0;i<S_times;i=i+1)
108
        begin
109
            if(F_gen[C_PRIMPOLY_ORDER-1])
110
                    F_gen = (F_gen<<1) ^ C_PRIM_POLY[C_PRIMPOLY_ORDER-1:0];
111
                else
112
                    F_gen = (F_gen<<1);
113
        end
114
end
115
endfunction
116
 
117
//encode polynomial generation
118
function [C_GEN_WIDTH:0] F_GEN_POLY;
119
input red;
120
integer i,j,k;
121
integer pointer;
122
reg [2**C_PRIMPOLY_ORDER-2:0] S_flag;
123
reg [C_PRIMPOLY_ORDER-1:0] S_temp [C_GEN_WIDTH:0]; //every reg is C_PRIMPOLY_ORDER width, represent a element 
124
reg [C_PRIMPOLY_ORDER-1:0] S_temp2;
125
begin
126
        F_GEN_POLY = 0;
127
        for(i=0;i<=C_PRIMPOLY_ORDER;i=i+1)
128
                S_temp[i] = C_PRIM_POLY[i];                //least C_PRIMPOLY_ORDER bits are eigenpolynomial
129
        for(i=C_PRIMPOLY_ORDER+1;i<=C_GEN_WIDTH;i=i+1)
130
                S_temp[i] = 0;
131
        for(i=1;i<C_COEF_NUM;i=i+1)    //encode polynomial include C_COEF_NUM polynomials
132
        begin
133
                S_flag = 0;
134
            for(j=1;j<=C_PRIMPOLY_ORDER;j=j+1)  //each polynomial have at most C_PRIMPOLY_ORDER element
135
                begin
136
                        pointer = (2*i+1)*(2**(j-1));
137
                        while(pointer>(2**C_PRIMPOLY_ORDER-2))
138
                                pointer = pointer - (2**C_PRIMPOLY_ORDER-1);
139
                    if(!S_flag[pointer])            //flag is a marker to indicate element exists or not
140
                        begin
141
                            S_flag[pointer] = 1;
142
                                S_temp2 = F_gen(1,pointer);
143
                                for(k=C_GEN_WIDTH-1;k>0;k=k-1)   //each polynomial have at most C_PRIMPOLY_ORDER multiplication
144
                                begin
145
                                    S_temp[k]= F_mult(S_temp[k],S_temp2) ^ S_temp[k-1]; //all the reg need to shift in each multiplication
146
                                end
147
                                S_temp[0] = F_mult(S_temp[0],S_temp2);
148
                                S_temp[C_GEN_WIDTH] = S_temp[C_GEN_WIDTH-1];
149
                        end
150
                end
151
        end
152
        for(i=0;i<C_GEN_WIDTH;i=i+1)
153
        F_GEN_POLY[i] = (S_temp[i] == 1);     //finally the S_temp should only be 1 or 0
154
end
155
endfunction
156
 
157
//width calculation
158
function integer GETASIZE;
159
input integer a;
160
integer i;
161
begin
162
    for(i=1;(2**i)<=a;i=i+1)
163
      begin
164
      end
165
    GETASIZE = i;
166
end
167
endfunction
168
 
169
//polynomial multiplication between encode polynomial and input data
170
function [C_GEN_WIDTH-1:0] F_reg_update;
171
input [C_GEN_WIDTH-1:0] S_reg_ori;
172
input [C_DWIDTH-1:0] S_data;
173
integer i;
174
reg S_temp1;
175
begin
176
        F_reg_update = S_reg_ori;
177
        for(i=0;i<C_DWIDTH;i=i+1)
178
        begin
179
                S_temp1 = F_reg_update[C_GEN_WIDTH-1] ^ S_data[C_DWIDTH-1-i];
180
                F_reg_update[C_GEN_WIDTH-1:0] = {F_reg_update[C_GEN_WIDTH-2:0],1'b0} ^ ({C_GEN_WIDTH{S_temp1}} & C_GENPOLY[C_GEN_WIDTH-1:0]);
181
        end
182
end
183
endfunction
184
 
185
//-----------------------------------------------
186
//encode
187
//-----------------------------------------------
188
always @(posedge I_clk)
189
begin
190
        if(I_data_v)
191
            S_reg <= F_reg_update(S_reg,I_data);
192
        else if(S_ecc_v)
193
            S_reg <= S_reg << C_DWIDTH;
194
end
195
 
196
//output counter
197
always @(posedge I_clk)
198
begin
199
    if(S_ecc_v)
200
            S_ecc_cnt <= S_ecc_cnt + 'd1;
201
        else
202
            S_ecc_cnt <= 'd0;
203
end
204
 
205
always @(posedge I_clk)
206
begin
207
    if(I_data_eof && I_data_v)
208
            S_ecc_v <= 1'b1;
209
        else if(S_ecc_cnt == C_ECC_PERIOD && S_ecc_v)
210
            S_ecc_v <= 1'b0;
211
end
212
 
213
//data out
214
always @(posedge I_clk)
215
begin
216
    if(S_ecc_v)
217
            O_data <= (C_GEN_WIDTH >= C_DWIDTH) ? S_reg[C_GEN_WIDTH-1-:C_DWIDTH] : (S_reg << (C_DWIDTH-C_GEN_WIDTH));
218
        else
219
            O_data <= I_data;
220
 
221
        O_data_v <= I_data_v || S_ecc_v;
222
        O_data_sof <= I_data_sof;
223
        O_data_eof <= (S_ecc_cnt == C_ECC_PERIOD) && S_ecc_v;
224
end
225
 
226
endmodule

powered by: WebSVN 2.1.0

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