URL
https://opencores.org/ocsvn/rs_decoder_31_19_6/rs_decoder_31_19_6/trunk
Subversion Repositories rs_decoder_31_19_6
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/tags/rel-1_0/KESBLOCK.V
0,0 → 1,457
//*******************************************************************// |
// This Key Equation Solver (KES) block implements reformulated // |
// inverse-free Berlekamp-Massey algorithm. The inverse-free // |
// Berlekamp-Massey is described by Irving S. Reed, M.T. Smith // |
// and T.K. Truong in their paper entitled "VLSI design of // |
// inverse-free Berlekamp-Massey (BM) algorithm" in Proc. IEEE, // |
// Sept 1991. With the algorithm, inverse/division operation is not // |
// needed. Hence, it simplifies the implementation of // |
// Berlekamp-Massey algorithm. // |
// Then, in the paper entitled "High speed architectures for // |
// Reed-Solomon Decoders" in IEEE Trans. VLSI Systems, October 2001, // |
// Dilip P. Sarwate and Naresh R. Shanbhag proposed a reformulated // |
// version of the inverse-free algorithm. The reformulated algorithm // |
// is aimed mainly to reduce critical path delay and also to // |
// simplify inverse-free algorithm implementation even more. // |
//*******************************************************************// |
|
module KES_block(active_kes, clock1, clock2, reset, syndvalue0, syndvalue1, |
syndvalue2, syndvalue3, syndvalue4, syndvalue5, syndvalue6, |
syndvalue7, syndvalue8, syndvalue9, syndvalue10, syndvalue11, |
lambda0, lambda1, lambda2, lambda3, lambda4, lambda5, |
lambda6, homega0, homega1, homega2, homega3, homega4, |
homega5, lambda_degree, finish); |
|
input active_kes, clock1, clock2, reset; |
input [4:0] syndvalue0, syndvalue1, syndvalue2, |
syndvalue3, syndvalue4, syndvalue5, syndvalue6, syndvalue7, |
syndvalue8, syndvalue9, syndvalue10, syndvalue11; |
output [4:0] lambda0, lambda1, lambda2, lambda3, lambda4, lambda5, lambda6; |
output [4:0] homega0, homega1, homega2, homega3, homega4, homega5; |
output [2:0] lambda_degree; |
output finish; |
|
wire load, hold, init, iter_control; |
wire [4:0] delta0, delta1, delta2, delta3, delta4, delta5, delta6, |
delta7, delta8, delta9, delta10, delta11, delta12, delta13, |
delta14, delta15, delta16, delta17, delta18; |
wire [4:0] gamma, delta; |
wire koefcomp1, koefcomp2, koefcomp3, koefcomp4, koefcomp5, koefcomp6; |
|
|
PE PE0(delta1, syndvalue0, gamma, delta, clock1, load, init, |
hold, iter_control, delta0); |
PE PE1(delta2, syndvalue1, gamma, delta, clock1, load, init, |
hold, iter_control, delta1); |
PE PE2(delta3, syndvalue2, gamma, delta, clock1, load, init, |
hold, iter_control, delta2); |
PE PE3(delta4, syndvalue3, gamma, delta, clock1, load, init, |
hold, iter_control, delta3); |
PE PE4(delta5, syndvalue4, gamma, delta, clock1, load, init, |
hold, iter_control, delta4); |
PE PE5(delta6, syndvalue5, gamma, delta, clock1, load, init, |
hold, iter_control, delta5); |
PE PE6(delta7, syndvalue6, gamma, delta, clock1, load, init, |
hold, iter_control, delta6); |
PE PE7(delta8, syndvalue7, gamma, delta, clock1, load, init, |
hold, iter_control, delta7); |
PE PE8(delta9, syndvalue8, gamma, delta, clock1, load, init, |
hold, iter_control, delta8); |
PE PE9(delta10, syndvalue9, gamma, delta, clock1, load, init, |
hold, iter_control, delta9); |
PE PE10(delta11, syndvalue10, gamma, delta, clock1, load, init, |
hold, iter_control, delta10); |
PE PE11(delta12, syndvalue11, gamma, delta, clock1, load, init, |
hold, iter_control, delta11); |
PE_12 PE12(delta13, gamma, delta, clock1, load, init, |
hold, iter_control, delta12); |
PE_12 PE13(delta14, gamma, delta, clock1, load, init, |
hold, iter_control, delta13); |
PE_12 PE14(delta15, gamma, delta, clock1, load, init, |
hold, iter_control, delta14); |
PE_12 PE15(delta16, gamma, delta, clock1, load, init, |
hold, iter_control, delta15); |
PE_12 PE16(delta17, gamma, delta, clock1, load, init, |
hold, iter_control, delta16); |
PE_12 PE17(delta18, gamma, delta, clock1, load, init, |
hold, iter_control, delta17); |
PE_18 PE18(delta, clock1, load, init, hold, iter_control, |
delta18); |
control mcontrol(delta0, gamma, active_kes, reset, delta, iter_control, |
finish, load, init, hold, clock1, clock2); |
|
assign homega0 = delta0; |
assign homega1 = delta1; |
assign homega2 = delta2; |
assign homega3 = delta3; |
assign homega4 = delta4; |
assign homega5 = delta5; |
|
assign lambda0 = delta6; |
assign lambda1 = delta7; |
assign lambda2 = delta8; |
assign lambda3 = delta9; |
assign lambda4 = delta10; |
assign lambda5 = delta11; |
assign lambda6 = delta12; |
|
// this statements below counts degree of error location polynomial |
// (lambda) |
assign koefcomp1 = (lambda1[0]|lambda1[1])|(lambda1[2]|lambda1[3])| |
lambda1[4]; |
assign koefcomp2 = (lambda2[0]|lambda2[1])|(lambda2[2]|lambda2[3])| |
lambda2[4]; |
assign koefcomp3 = (lambda3[0]|lambda3[1])|(lambda3[2]|lambda3[3])| |
lambda3[4]; |
assign koefcomp4 = (lambda4[0]|lambda4[1])|(lambda4[2]|lambda4[3])| |
lambda4[4]; |
assign koefcomp5 = (lambda5[0]|lambda5[1])|(lambda5[2]|lambda5[3])| |
lambda5[4]; |
assign koefcomp6 = (lambda6[0]|lambda6[1])|(lambda6[2]|lambda6[3])| |
lambda6[4]; |
priority_encoder pencoder(koefcomp1,koefcomp2,koefcomp3,koefcomp4, |
koefcomp5,koefcomp6, lambda_degree); |
|
endmodule |
|
|
|
//************************************************************// |
module control(delta0_in, gamma, active_kes, reset, delta0_out, |
iter_control, finish, load, init, hold, |
clock1, clock2); |
|
input [4:0] delta0_in; |
input clock1, clock2, active_kes, reset; |
output [4:0] delta0_out, gamma; |
output iter_control, finish, load, hold, init; |
|
reg [3:0] cntr; |
reg load, hold, init, finish; |
wire [4:0] kr, inv_kr, outadder; |
wire [4:0] outmux1, outmux2; |
wire zerodetect, negdetect; |
|
wire [4:0] incr; |
wire carrybit; |
|
parameter [2:0] st0=0, st1=1, st2=2, st3=3, st4=4, st5=5; |
reg [2:0] state, nxt_state; |
|
// Counter // |
always@(posedge clock1) |
begin |
if(load) |
cntr <= cntr + 1; |
else |
cntr <= 4'b0; |
end |
|
//******// |
// FSM // |
//******// |
always@(active_kes or cntr or state) |
begin |
case(state) |
st0 : begin |
if(active_kes) |
nxt_state = st1; |
else |
nxt_state = st0; |
end |
st1 : nxt_state = st2; |
st2 : begin |
if(cntr == 12) |
nxt_state = st3; |
else |
nxt_state = st2; |
end |
st3 : nxt_state = st4; |
st4 : begin |
if(active_kes) |
nxt_state = st4; |
else |
nxt_state = st0; |
end |
default: nxt_state = st0; |
endcase |
end |
|
always@(posedge clock2 or negedge reset) |
begin |
if(~reset) |
state = st0; |
else |
state = nxt_state; |
end |
|
always@(state) |
begin |
case(state) |
st0 : begin //start state |
init = 0; |
finish = 0; |
load = 0; |
hold = 0; |
end |
st1 : begin //initialization state |
init = 1; |
finish = 0; |
load = 0; |
hold = 0; |
end |
st2 : begin //computation state |
finish = 0; |
load = 1; |
hold = 0; |
init = 0; |
end |
st3 : begin //finish state |
finish = 1; |
load = 0; |
hold = 1; |
init = 0; |
end |
st4 : begin //hold output data |
finish = 0; |
load = 0; |
hold = 1; |
init = 0; |
end |
default: begin |
finish = 0; |
load = 0; |
hold = 0; |
init = 0; |
end |
endcase |
end |
|
assign incr = 1; |
assign carrybit = 0; |
|
assign zerodetect = (delta0_in[0]|delta0_in[1])|(delta0_in[2]|delta0_in[3])|delta0_in[4]; |
assign negdetect = ~kr[4]; |
assign iter_control = zerodetect & negdetect; |
assign inv_kr = ~kr; |
assign delta0_out = delta0_in; |
|
mux2_to_1 multiplexer1(gamma, delta0_in, outmux1, iter_control); |
mux2_to_1 multiplexer2(outadder, inv_kr, outmux2, iter_control); |
fulladder adder(kr, incr, carrybit, outadder); |
regamma reggamma(outmux1, gamma, load, init, clock1); |
regkr regkr(outmux2, kr, load, init, clock1); |
|
endmodule |
|
|
//****************************************// |
// Full Adder 5 bit // |
// carry bit for MSB cell is discarded // |
//****************************************// |
module fulladder(in1, in2, carryin, out); |
input [4:0] in1, in2; |
input carryin; |
output [4:0] out; |
|
wire carry0, carry1, carry2, carry3; |
|
assign carry0 = ((in1[0] ^ in2[0])&carryin) | (in1[0]&in2[0]); |
assign carry1 = ((in1[1] ^ in2[1])&carry0) | (in1[1]&in2[1]); |
assign carry2 = ((in1[2] ^ in2[2])&carry1) | (in1[2]&in2[2]); |
assign carry3 = ((in1[3] ^ in2[3])&carry2) | (in1[3]&in2[3]); |
|
assign out[0] = in1[0] ^ in2[0] ^ carryin; |
assign out[1] = in1[1] ^ in2[1] ^ carry0; |
assign out[2] = in1[2] ^ in2[2] ^ carry1; |
assign out[3] = in1[3] ^ in2[3] ^ carry2; |
assign out[4] = in1[4] ^ in2[4] ^ carry3; |
|
endmodule |
|
|
//*********************************************// |
// register for storing gamma with synchronous // |
// load and initialize // |
//*********************************************// |
module regamma(datain, dataout, load, initialize, clock); |
|
input [4:0] datain; |
input load, initialize; |
input clock; |
output [4:0] dataout; |
reg [4:0] out; |
|
always @(posedge clock) |
begin |
if(initialize) |
out <= 5'b10000; |
else if(load) |
out <= datain; |
else |
out <= 5'b0; |
end |
|
assign dataout = out; |
|
endmodule |
|
//********************************************// |
// register for storing k(r) with synchronous // |
// load and initialize // |
//********************************************// |
module regkr(datain, dataout, load, initialize, clock); |
|
input [4:0] datain; |
input load, initialize; |
input clock; |
output [4:0] dataout; |
reg [4:0] out; |
|
always @(posedge clock) |
begin |
if(initialize) |
out <= 5'b0; |
else if(load) |
out <= datain; |
else |
out <= 5'b0; |
end |
|
assign dataout = out; |
|
endmodule |
|
|
//******************// |
// Priority Encoder // |
//******************// |
module priority_encoder(in1,in2,in3,in4,in5,in6,out); |
|
input in1, in2, in3, in4, in5, in6; |
output [2:0] out; |
reg [2:0] out; |
|
always@({in6,in5,in4,in3,in2,in1}) |
begin |
if(in6==1) out = 6; |
else if(in5==1) out = 5; |
else if(in4==1) out = 4; |
else if(in3==1) out = 3; |
else if(in2==1) out = 2; |
else if(in1==1) out = 1; |
else out = 3'b0; |
end |
endmodule |
|
|
//****************************************************************// |
module PE(delta_cflex_in, syndval, gamma, delta, clock, load, init, |
hold, iter_control, delta_cflex_out); |
|
input [4:0] delta_cflex_in, syndval; |
input [4:0] gamma; |
input [4:0] delta; |
input clock, load, hold, iter_control, init; |
output [4:0] delta_cflex_out; |
|
wire [4:0] outmult1, outmult2, outreg1, outreg2, outmux, outadder; |
|
lcpmult multiplier1(delta_cflex_in, gamma, outmult1); |
lcpmult multiplier2(delta, outreg1, outmult2); |
register_pe reg1(outadder, syndval, outreg2 , load, init, hold, clock); |
register_pe reg2(outmux, syndval, outreg1 , load, init, hold, clock); |
mux2_to_1 multiplexer(outreg1, delta_cflex_in, outmux, iter_control); |
|
assign outadder[4] = outmult2[4] ^ outmult1[4]; |
assign outadder[3] = outmult2[3] ^ outmult1[3]; |
assign outadder[2] = outmult2[2] ^ outmult1[2]; |
assign outadder[1] = outmult2[1] ^ outmult1[1]; |
assign outadder[0] = outmult2[0] ^ outmult1[0]; |
|
assign delta_cflex_out = outreg2; |
|
endmodule |
|
//***********************************************************// |
module PE_12(delta_cflex_in, gamma, delta, clock, load, init, |
hold, iter_control, delta_cflex_out); |
|
input [4:0] delta_cflex_in; |
input [4:0] gamma; |
input [4:0] delta; |
input clock, load, hold, iter_control, init; |
output [4:0] delta_cflex_out; |
|
wire [4:0] outmult1, outmult2, outreg1, outreg2, outmux, outadder; |
wire [4:0] initdata; |
|
assign initdata = 5'b0; |
|
lcpmult multiplier1(delta_cflex_in, gamma, outmult1); |
lcpmult multiplier2(delta, outreg1, outmult2); |
register_pe reg1(outadder, initdata, outreg2 , load, init, hold, clock); |
register_pe reg2(outmux, initdata, outreg1 , load, init, hold, clock); |
mux2_to_1 multiplexer(outreg1, delta_cflex_in, outmux, iter_control); |
|
assign outadder[4] = outmult2[4] ^ outmult1[4]; |
assign outadder[3] = outmult2[3] ^ outmult1[3]; |
assign outadder[2] = outmult2[2] ^ outmult1[2]; |
assign outadder[1] = outmult2[1] ^ outmult1[1]; |
assign outadder[0] = outmult2[0] ^ outmult1[0]; |
|
assign delta_cflex_out = outreg2; |
|
endmodule |
|
|
//******************************************************// |
module PE_18(delta, clock, load, init, hold, iter_control, |
delta_cflex_out); |
|
input [4:0] delta; |
input clock, load, init, hold, iter_control; |
output [4:0] delta_cflex_out; |
|
wire [4:0] outmult, outreg1, outreg2, outmux; |
wire [4:0] initdata; |
wire [4:0] delta_cflex_19; |
|
assign initdata = 5'b10000; |
assign delta_cflex_19 = 5'b0; |
|
lcpmult multiplier(delta, outreg1, outmult); |
register_pe reg1(outmult, initdata, outreg2 , load, init, hold, clock); |
register_pe reg2(outmux, initdata, outreg1 , load, init, hold, clock); |
mux2_to_1 multiplexer(outreg1, delta_cflex_19, outmux, iter_control); |
|
assign delta_cflex_out = outreg2; |
|
endmodule |
|
|
//*****************************************************// |
//PE Register with synchronous load, intialize, hold // |
module register_pe(datain, initdata, dataout, load, initialize, hold, clock); |
|
input [4:0] datain, initdata; |
input load, hold, initialize; |
input clock; |
output [4:0] dataout; |
reg [4:0] out; |
|
always @(posedge clock) |
begin |
if(initialize) |
out <= initdata; |
else if(load) |
out <= datain; |
else if(hold) |
out <= out; |
else |
out <= 5'b0; |
end |
|
assign dataout = out; |
|
endmodule |
/tags/rel-1_0/testbench.v
0,0 → 1,237
///*************************************************************/// |
/// /// |
/// Reed-Solomon Decoder (31,19,6) /// |
/// /// |
/// /// |
/// Author : Rudy Dwi Putra /// |
/// rudy.dp@gmail.com /// |
/// /// |
///*************************************************************/// |
/// /// |
/// Copyright (C) 2006 Rudy Dwi Putra /// |
/// rudy.dp@gmail.com /// |
/// /// |
/// This source file may be used and distributed without /// |
/// restriction provided that this copyright statement is not /// |
/// removed from the file and that any derivative work contains /// |
/// the original copyright notice and the associated disclaimer./// |
/// /// |
/// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY /// |
/// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED /// |
/// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS /// |
/// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR /// |
/// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, /// |
/// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES /// |
/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE /// |
/// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR /// |
/// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF /// |
/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT /// |
/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT /// |
/// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE /// |
/// POSSIBILITY OF SUCH DAMAGE. /// |
/// /// |
///*************************************************************/// |
|
//***************************************// |
// Testbench for RS Decoder (31, 19, 6) // |
//***************************************// |
|
module testbench_rsdecoder; |
|
reg [4:0] recword; |
reg clock1, clock2; |
reg start, reset; |
|
//******************************************************// |
// ready = if set to 1, decoder is ready to input or it // |
// is inputting new data // |
// dataoutstart = flag the first symbol of outputted // |
// received word. // |
// dataoutend = flag the last symbol of outputted // |
// received word. // |
// errfound = set to 1, if one of syndrome values // |
// is not zero. // |
// decode_fail = set to 1, if decoder fails to correct // |
// the received word. // |
//******************************************************// |
wire ready, decode_fail, errfound, dataoutstart, dataoutend; |
wire [4:0] corr_recword; |
|
parameter [5:0] clk_period = 50; |
|
initial |
begin |
recword = 5'b0; |
start = 0; |
reset = 0; |
end |
|
//**********// |
// clock1 // |
//**********// |
initial |
begin |
clock1 = 0; |
forever #(clk_period/2) clock1 = ~clock1; |
end |
|
//**********// |
// clock2 // |
//**********// |
initial |
begin |
clock2 = 1; |
forever #(clk_period/2) clock2 = ~clock2; |
end |
|
//***********************************************// |
// This section defines feeding of received word // |
// and start signal. Start signal is active 1 // |
// clock cycle before first symbol of received // |
// word. All input and output synchronize with // |
// clock2. First received word contains no error // |
// symbol. Thus, all syndrome values will be zero// |
// and decoder will pass the received word. // |
// Second received word contains 6 error symbol. // |
// Decoder will determine its error locator // |
// and error evaluator polynomial in KES block. // |
// Then, it calculates error values in CSEE // |
// block. Third received word contains 8 error // |
// symbol. Decoder can't correct the error and // |
// at the end of outputted received word, it will// |
// set decode_fail to 1. // |
//***********************************************// |
initial |
begin |
#(clk_period) reset = 1; |
|
//start has to be active 1 clock cycle before first recword, |
//otherwise decoder will output wrong recword. |
#(clk_period) start = 1; |
#(clk_period) start = 0; |
|
//First received word contains no error symbol. |
//The decoder should give errfound = 0 at the end |
//of syndrome calculation stage. |
recword = 5'b10100; |
#(clk_period) recword = 5'b00100; |
#(clk_period) recword = 5'b00101; |
#(clk_period) recword = 5'b10001; |
#(clk_period) recword = 5'b10110; |
#(clk_period) recword = 5'b00001; |
#(clk_period) recword = 5'b00010; |
#(clk_period) recword = 5'b11100; |
#(clk_period) recword = 5'b00011; |
#(clk_period) recword = 5'b10001; |
#(clk_period) recword = 5'b00110; |
#(clk_period) recword = 5'b00111; |
#(clk_period) recword = 5'b01010; |
#(clk_period) recword = 5'b11111; |
#(clk_period) recword = 5'b01011; |
#(clk_period) recword = 5'b10100; |
#(clk_period) recword = 5'b00100; |
#(clk_period) recword = 5'b00101; |
#(clk_period) recword = 5'b00001; |
#(clk_period) recword = 5'b10111; |
#(clk_period) recword = 5'b10100; |
#(clk_period) recword = 5'b00010; |
#(clk_period) recword = 5'b10110; |
#(clk_period) recword = 5'b00100; |
#(clk_period) recword = 5'b01011; |
#(clk_period) recword = 5'b00110; |
#(clk_period) recword = 5'b11110; |
#(clk_period) recword = 5'b10100; |
#(clk_period) recword = 5'b11111; |
#(clk_period) recword = 5'b01010; |
#(clk_period) recword = 5'b11110; |
#(clk_period) recword = 5'b0; |
|
|
#(18*clk_period) start = 1; |
#(clk_period) start = 0; |
|
//Second received word contains 6 error symbols. |
//The decoder sets errfound = 1, and activates |
//KES block and then CSEE block. Because the |
//number of errors is equal to correction capability |
//of the decoder, decoder can correct the received |
//word. |
recword = 5'b01100; //it should be 5'b10100 |
#(clk_period) recword = 5'b00100; |
#(clk_period) recword = 5'b00101; |
#(clk_period) recword = 5'b10001; |
#(clk_period) recword = 5'b10110; |
#(clk_period) recword = 5'b00001; |
#(clk_period) recword = 5'b00110; //it should be 5'b00010 |
#(clk_period) recword = 5'b11100; |
#(clk_period) recword = 5'b00011; |
#(clk_period) recword = 5'b10001; |
#(clk_period) recword = 5'b00110; |
#(clk_period) recword = 5'b00101; //it should be 5'b00111 |
#(clk_period) recword = 5'b01010; |
#(clk_period) recword = 5'b11111; |
#(clk_period) recword = 5'b11111; //it should be 5'b01011 |
#(clk_period) recword = 5'b10100; |
#(clk_period) recword = 5'b00100; |
#(clk_period) recword = 5'b00101; |
#(clk_period) recword = 5'b00001; |
#(clk_period) recword = 5'b10111; |
#(clk_period) recword = 5'b01101; //it should be 5'b10100 |
#(clk_period) recword = 5'b00010; |
#(clk_period) recword = 5'b10110; |
#(clk_period) recword = 5'b00100; |
#(clk_period) recword = 5'b01011; |
#(clk_period) recword = 5'b00110; |
#(clk_period) recword = 5'b11110; |
#(clk_period) recword = 5'b10100; |
#(clk_period) recword = 5'b10101; //it should be 5'b11111 |
#(clk_period) recword = 5'b01010; |
#(clk_period) recword = 5'b11110; |
#(clk_period) recword = 5'b0; |
|
#(20*clk_period) start = 1; |
#(clk_period) start = 0; |
//Third received word contains 8 error symbols. |
//Because the number of errors is greater than correction |
//capability, decoder will resume decoding failure at the end of |
//outputted received word. |
recword = 5'b10100; |
#(clk_period) recword = 5'b00100; |
#(clk_period) recword = 5'b00101; |
#(clk_period) recword = 5'b10001; |
#(clk_period) recword = 5'b10110; |
#(clk_period) recword = 5'b00100; //it should be 5'b00001 |
#(clk_period) recword = 5'b00010; |
#(clk_period) recword = 5'b11100; |
#(clk_period) recword = 5'b10010; //it should be 5'b00011 |
#(clk_period) recword = 5'b10101; //it should be 5'b10001 |
#(clk_period) recword = 5'b00110; |
#(clk_period) recword = 5'b10011; //it should be 5'b00111 |
#(clk_period) recword = 5'b01010; |
#(clk_period) recword = 5'b11111; |
#(clk_period) recword = 5'b01011; |
#(clk_period) recword = 5'b10100; |
#(clk_period) recword = 5'b00110; //it should be 5'b00100 |
#(clk_period) recword = 5'b00101; |
#(clk_period) recword = 5'b00100; //it should be 5'b00001 |
#(clk_period) recword = 5'b10110; //it should be 5'b10111 |
#(clk_period) recword = 5'b10100; |
#(clk_period) recword = 5'b00010; |
#(clk_period) recword = 5'b10110; |
#(clk_period) recword = 5'b00100; |
#(clk_period) recword = 5'b01011; |
#(clk_period) recword = 5'b00110; |
#(clk_period) recword = 5'b11110; |
#(clk_period) recword = 5'b10010; //it should be 5'b10100 |
#(clk_period) recword = 5'b11111; |
#(clk_period) recword = 5'b01010; |
#(clk_period) recword = 5'b11110; |
#(clk_period) recword = 5'b0; |
end |
|
|
RSDecoder rsdecoder(recword, start, clock1, clock2, reset, ready, |
errfound, decode_fail, dataoutstart, dataoutend, |
corr_recword); |
|
endmodule |
/tags/rel-1_0/SCBLOCK.V
0,0 → 1,417
//*****************************************************************// |
// Syndrome Computation // |
// This block consists mainly of 12 cells. Each cell computes // |
// syndrome value Si, for i=0,...,11. // |
// At the end of received word block, all cells store the syndrome // |
// values, while SC block set its flag (errdetect) if one or more // |
// syndrome values are not zero. // |
// Ref.: "High-speed VLSI Architecture for Parallel Reed-Solomon // |
// Decoder", IEEE Trans. on VLSI, April 2003. // |
//*****************************************************************// |
module SCblock(recword, clock1, clock2, active_sc, reset, syndvalue0, |
syndvalue1, syndvalue2, syndvalue3, syndvalue4, |
syndvalue5, syndvalue6, syndvalue7, syndvalue8, |
syndvalue9, syndvalue10, syndvalue11, errdetect, |
en_sccell, evalsynd, holdsynd); |
|
input [4:0] recword; |
input clock1, clock2, active_sc, reset, evalsynd, holdsynd, en_sccell; |
output [4:0] syndvalue0, syndvalue1, syndvalue2, syndvalue3, syndvalue4, |
syndvalue5, syndvalue6, syndvalue7, syndvalue8, syndvalue9, |
syndvalue10, syndvalue11; |
output errdetect; |
|
reg errdetect; |
reg [1:0] state, nxt_state; |
parameter [1:0] st0=0, st1=1, st2=2; |
|
always@(state or active_sc or evalsynd) |
begin |
case(state) |
st0: begin |
if(active_sc) |
nxt_state <= st1; |
else |
nxt_state <= st0; |
end |
st1: begin |
if(evalsynd) |
nxt_state <= st2; |
else |
nxt_state <= st1; |
end |
st2: nxt_state <= st0; |
default: nxt_state <= st0; |
endcase |
end |
|
always@(posedge clock2 or negedge reset) |
begin |
if(~reset) |
state <= st0; |
else |
state <= nxt_state; |
end |
|
always@(state or syndvalue0 or syndvalue1 or syndvalue2 or syndvalue3 or |
syndvalue4 or syndvalue5 or syndvalue6 or syndvalue7 or syndvalue8 or |
syndvalue9 or syndvalue10 or syndvalue11) |
begin |
case(state) |
st0: errdetect <= 0; |
st1: errdetect <= 0; |
st2: begin |
if (syndvalue0 || syndvalue1 || syndvalue2 || syndvalue3 || |
syndvalue4 || syndvalue5 || syndvalue6 || syndvalue7 || |
syndvalue8 || syndvalue9 || syndvalue10 || syndvalue11) |
errdetect <= 1; |
else |
errdetect <= 0; |
end |
default:errdetect = 0; |
endcase |
end |
|
syndcell_0 cell_0(recword, clock1, en_sccell, holdsynd, syndvalue0); |
syndcell_1 cell_1(recword, clock1, en_sccell, holdsynd, syndvalue1); |
syndcell_2 cell_2(recword, clock1, en_sccell, holdsynd, syndvalue2); |
syndcell_3 cell_3(recword, clock1, en_sccell, holdsynd, syndvalue3); |
syndcell_4 cell_4(recword, clock1, en_sccell, holdsynd, syndvalue4); |
syndcell_5 cell_5(recword, clock1, en_sccell, holdsynd, syndvalue5); |
syndcell_6 cell_6(recword, clock1, en_sccell, holdsynd, syndvalue6); |
syndcell_7 cell_7(recword, clock1, en_sccell, holdsynd, syndvalue7); |
syndcell_8 cell_8(recword, clock1, en_sccell, holdsynd, syndvalue8); |
syndcell_9 cell_9(recword, clock1, en_sccell, holdsynd, syndvalue9); |
syndcell_10 cell_10(recword, clock1, en_sccell, holdsynd, syndvalue10); |
syndcell_11 cell_11(recword, clock1, en_sccell, holdsynd, syndvalue11); |
|
endmodule |
|
|
//*****************************/ |
// Syndrome Computation Cells // |
//****************************// |
|
//**************************************************// |
//syndcell_0 computes R(alpha^19) for 31 clock cycles// |
//**************************************************// |
module syndcell_0(recword, clock, enable, hold, synvalue0); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue0; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^19 |
assign outmult[0] = outreg[3] ^ outreg[4]; |
assign outmult[1] = outreg[0] ^ outreg[4]; |
assign outmult[2] = (outreg[0] ^ outreg[1]) ^ (outreg[3] ^ outreg[4]); |
assign outmult[3] = (outreg[1] ^ outreg[2]) ^ outreg[4]; |
assign outmult[4] = outreg[2] ^ outreg[3]; |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue0 = outreg; |
|
endmodule |
|
//**************************************************// |
//syndcell_1 computes R(alpha^20) for 31 clock cycles// |
//**************************************************// |
module syndcell_1(recword, clock, enable, hold, synvalue1); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue1; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^20 |
assign outmult[0] = outreg[2] ^ outreg[3]; |
assign outmult[1] = outreg[3] ^ outreg[4]; |
assign outmult[2] = (outreg[0] ^ outreg[4]) ^ (outreg[2] ^ outreg[3]); |
assign outmult[3] = (outreg[0] ^ outreg[1]) ^ (outreg[3] ^ outreg[4]); |
assign outmult[4] = (outreg[1] ^ outreg[2]) ^ outreg[4]; |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue1 = outreg; |
|
endmodule |
|
//**************************************************// |
//syndcell_2 computes R(alpha^21) for 31 clock cycles// |
//**************************************************// |
module syndcell_2(recword, clock, enable, hold, synvalue2); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue2; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^21 |
assign outmult[0] = (outreg[1] ^ outreg[2]) ^ outreg[4]; |
assign outmult[1] = outreg[2] ^ outreg[3]; |
assign outmult[2] = (outreg[1] ^ outreg[2]) ^ outreg[3]; |
assign outmult[3] = (outreg[0] ^ outreg[2]) ^ (outreg[3] ^ outreg[4]); |
assign outmult[4] = (outreg[0] ^ outreg[1]) ^ (outreg[3] ^ outreg[4]); |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue2 = outreg; |
|
endmodule |
|
//**************************************************// |
//syndcell_3 computes R(alpha^22) for 31 clock cycles// |
//**************************************************// |
module syndcell_3(recword, clock, enable, hold, synvalue3); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue3; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^22 |
assign outmult[0] = (outreg[0] ^ outreg[1]) ^ (outreg[3] ^ outreg[4]); |
assign outmult[1] = (outreg[1] ^ outreg[2]) ^ outreg[4]; |
assign outmult[2] = (outreg[0] ^ outreg[1]) ^ (outreg[2] ^ outreg[4]); |
assign outmult[3] = (outreg[1] ^ outreg[2]) ^ outreg[3]; |
assign outmult[4] = (outreg[0] ^ outreg[2]) ^ (outreg[3] ^ outreg[4]); |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue3 = outreg; |
|
endmodule |
|
//***************************************************// |
//syndcell_4 computes R(alpha^23) for 31 clock cycles// |
//**************************************************// |
module syndcell_4(recword, clock, enable, hold, synvalue4); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue4; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^23 |
assign outmult[0] = (outreg[0] ^ outreg[2]) ^ (outreg[3] ^ outreg[4]); |
assign outmult[1] = (outreg[0] ^ outreg[1]) ^ (outreg[3] ^ outreg[4]); |
assign outmult[2] = (outreg[0] ^ outreg[1]) ^ outreg[3]; |
assign outmult[3] = (outreg[0] ^ outreg[1]) ^ (outreg[2] ^ outreg[4]); |
assign outmult[4] = (outreg[1] ^ outreg[2]) ^ outreg[3]; |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue4 = outreg; |
|
endmodule |
|
//***************************************************// |
//syndcell_5 computes R(alpha^24) for 31 clock cycles// |
//***************************************************// |
module syndcell_5(recword, clock, enable, hold, synvalue5); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue5; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^24 |
assign outmult[0] = (outreg[1] ^ outreg[2]) ^ outreg[3]; |
assign outmult[1] = (outreg[0] ^ outreg[2]) ^ (outreg[3] ^ outreg[4]); |
assign outmult[2] = (outreg[0] ^ outreg[2]) ^ outreg[4]; |
assign outmult[3] = (outreg[0] ^ outreg[1]) ^ outreg[3]; |
assign outmult[4] = (outreg[0] ^ outreg[1]) ^ (outreg[2] ^ outreg[4]); |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue5 = outreg; |
|
endmodule |
|
//***************************************************// |
//syndcell_6 computes R(alpha^25) for 31 clock cycles// |
//***************************************************// |
module syndcell_6(recword, clock, enable, hold, synvalue6); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue6; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^25 |
assign outmult[0] = (outreg[0] ^ outreg[1]) ^ (outreg[2] ^ outreg[4]); |
assign outmult[1] = (outreg[1] ^ outreg[2]) ^ outreg[3]; |
assign outmult[2] = outreg[1] ^ outreg[3]; |
assign outmult[3] = (outreg[0] ^ outreg[2]) ^ outreg[4]; |
assign outmult[4] = (outreg[0] ^ outreg[1]) ^ outreg[3]; |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue6 = outreg; |
|
endmodule |
|
//***************************************************// |
//syndcell_7 computes R(alpha^26) for 31 clock cycles// |
//***************************************************// |
module syndcell_7(recword, clock, enable, hold, synvalue7); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue7; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^26 |
assign outmult[0] = (outreg[0] ^ outreg[1]) ^ outreg[3]; |
assign outmult[1] = (outreg[0] ^ outreg[1]) ^ (outreg[2] ^ outreg[4]); |
assign outmult[2] = outreg[0] ^ outreg[2]; |
assign outmult[3] = outreg[1] ^ outreg[3]; |
assign outmult[4] = (outreg[0] ^ outreg[2]) ^ outreg[4]; |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue7 = outreg; |
|
endmodule |
|
//***************************************************// |
//syndcell_8 computes R(alpha^27) for 31 clock cycles// |
//***************************************************// |
module syndcell_8(recword, clock, enable, hold, synvalue8); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue8; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^27 |
assign outmult[0] = (outreg[0] ^ outreg[2]) ^ outreg[4]; |
assign outmult[1] = (outreg[0] ^ outreg[1]) ^ outreg[3]; |
assign outmult[2] = outreg[1]; |
assign outmult[3] = outreg[0] ^ outreg[2]; |
assign outmult[4] = outreg[1] ^ outreg[3]; |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue8 = outreg; |
|
endmodule |
|
//***************************************************// |
//syndcell_9 computes R(alpha^28) for 31 clock cycles// |
//***************************************************// |
module syndcell_9(recword, clock, enable, hold, synvalue9); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue9; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^28 |
assign outmult[0] = outreg[1] ^ outreg[3]; |
assign outmult[1] = (outreg[0] ^ outreg[2]) ^ outreg[4]; |
assign outmult[2] = outreg[0]; |
assign outmult[3] = outreg[1]; |
assign outmult[4] = outreg[0] ^ outreg[2]; |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue9 = outreg; |
|
endmodule |
|
//****************************************************// |
//syndcell_10 computes R(alpha^29) for 31 clock cycles// |
//****************************************************// |
module syndcell_10(recword, clock, enable, hold, synvalue10); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue10; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^29 |
assign outmult[0] = outreg[0] ^ outreg[2]; |
assign outmult[1] = outreg[1] ^ outreg[3]; |
assign outmult[2] = outreg[4]; |
assign outmult[3] = outreg[0]; |
assign outmult[4] = outreg[1]; |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue10 = outreg; |
|
endmodule |
|
//****************************************************// |
//syndcell_11 computes R(alpha^30) for 31 clock cycles// |
//****************************************************// |
module syndcell_11(recword, clock, enable, hold, synvalue11); |
|
input [0:4] recword; |
input clock; |
input enable, hold; |
output [0:4] synvalue11; |
|
wire [0:4] outreg; |
wire [0:4] outadder; |
wire [0:4] outmult; |
|
//multiply recword with constant alpha^30 |
assign outmult[0] = outreg[1]; |
assign outmult[1] = outreg[0] ^ outreg[2]; |
assign outmult[2] = outreg[3]; |
assign outmult[3] = outreg[4]; |
assign outmult[4] = outreg[0]; |
|
register5_wlh register5bit(outadder, outreg, enable, hold, clock); |
gfadder adder(recword, outmult, outadder); |
assign synvalue11 = outreg; |
|
endmodule |
/tags/rel-1_0/common_modules.v
0,0 → 1,129
//******************************************************// |
// This file contains definition of common modules used // |
// by higher level modules in RS Decoder // |
//******************************************************// |
|
//*************************// |
// Multiplexer 2 to 1 5bit // |
//*************************// |
module mux2_to_1(in1, in2 , out, sel); |
|
input [4:0] in1, in2; |
input sel; |
output [4:0] out; |
reg [4:0] out; |
|
always@(sel or in1 or in2) |
begin |
case(sel) |
0 : out = in1; |
1 : out = in2; |
default: out = in1; |
endcase |
end |
endmodule |
|
//**********************************************// |
//Register 5 bit with synchronous load and hold // |
//**********************************************// |
module register5_wlh(datain, dataout, load, hold, clock); |
|
input [4:0] datain; |
input load, hold; |
input clock; |
output [4:0] dataout; |
reg [4:0] out; |
|
always @(posedge clock) |
begin |
if(load) |
out <= datain; |
else if(hold) |
out <= out; |
else |
out <= 5'b0; |
end |
|
assign dataout = out; |
|
endmodule |
|
|
//**************************************// |
// Register 5 bit with synchronous load // |
//**************************************// |
module register5_wl(datain, dataout, clock, load); |
|
input [4:0] datain; |
output [4:0] dataout; |
input clock, load; |
reg [4:0] dataout; |
|
always@(posedge clock) |
begin |
if(load) |
dataout <= datain; |
else |
dataout <= 5'b0; |
end |
|
endmodule |
|
|
//**************// |
//GF(2^5) Adder // |
//**************// |
module gfadder(in1, in2, out); |
|
input [0:4] in1, in2; |
output [0:4] out; |
|
assign out[4] = in1[4] ^ in2[4]; |
assign out[3] = in1[3] ^ in2[3]; |
assign out[2] = in1[2] ^ in2[2]; |
assign out[1] = in1[1] ^ in2[1]; |
assign out[0] = in1[0] ^ in2[0]; |
|
endmodule |
|
|
//*********************************************// |
// GF(2^5) parallel multiplier is based on // |
// the design proposed by M. Anwar Hasan & // |
// A. Reyhani-Masoleh in their paper entitled // |
// "Low Complexity Bit Parallel Architectures // |
// for Polynomial Basis Multiplication over // |
// GF(2^m)" published in IEEE Transactions On // |
// Computer August 2004. // |
//*********************************************// |
module lcpmult(in1, in2, out); |
|
input [0:4] in1, in2; //in1[4] & in2[4] is MSB |
output [0:4] out; |
|
wire [4:0] intvald; //intermediate val d |
wire [3:0] intvale; //intermediate val e |
wire intvale_0ax; //intermediate val e'[0] |
|
assign intvald[0] = in1[0] & in2[0]; |
assign intvald[1] = (in1[1] & in2[0]) ^ (in1[0] & in2[1]); |
assign intvald[2] = (in1[2] & in2[0]) ^ ((in1[1] & in2[1]) ^ (in1[0] & in2[2])); |
assign intvald[3] = ((in1[3] & in2[0]) ^ (in1[2] & in2[1])) ^ ((in1[1] & in2[2]) ^ (in1[0] & in2[3])); |
assign intvald[4] = (((in1[4] & in2[0]) ^ (in1[3] & in2[1])) ^ (in1[2] & in2[2])) |
^ ((in1[1] & in2[3]) ^ (in1[0] & in2[4])); |
|
assign intvale[0] = ((in1[4] & in2[1]) ^ (in1[3] & in2[2])) ^ ((in1[2] & in2[3]) ^ (in1[1] & in2[4])); |
assign intvale[1] = ((in1[4] & in2[2]) ^ (in1[3] & in2[3])) ^ (in1[2] & in2[4]); |
assign intvale[2] = (in1[4] & in2[3]) ^ (in1[3] & in2[4]); |
assign intvale[3] = in1[4] & in2[4]; |
|
assign intvale_0ax = (intvale[0] ^ intvale[3]); |
|
assign out[0] = intvald[0] ^ intvale_0ax; |
assign out[1] = intvald[1] ^ intvale[1]; |
assign out[2] = (intvald[2] ^ intvale[2]) ^ intvale_0ax; |
assign out[3] = (intvald[3] ^ intvale[1]) ^ intvale[3]; |
assign out[4] = intvald[4] ^ intvale[2]; |
|
endmodule |
|
/tags/rel-1_0/controller.v
0,0 → 1,585
//****************************************************// |
// This controller provides timing synchronization // |
// among all four modules (SC, KES, CSEE and FIFO // |
// Registers). It consists of 2 FSMs that operate on // |
// different clock phases. // |
// With these FSMs, it is possible for SC block to // |
// get new received word data, while CSEE is still // |
// correcting old data. It is no need to wait the // |
// CSEE block to correct old data completely. // |
// So, it can minimize throughput bottleneck // |
// to only in KES block. // |
//****************************************************// |
|
module MainControl(start, reset, clock1, clock2, finish_kes, |
errdetect, rootcntr, lambda_degree, active_sc, |
active_kes, active_csee, evalsynd, holdsynd, |
errfound, decode_fail, ready, dataoutstart, |
dataoutend, shift_fifo, hold_fifo, en_infifo, |
en_outfifo, lastdataout, evalerror); |
|
input start, reset; |
input clock1, clock2; |
input errdetect, finish_kes; |
input [2:0] rootcntr, lambda_degree; |
output active_sc, active_kes, active_csee, ready; |
output evalsynd, holdsynd, errfound, decode_fail; |
output dataoutstart, dataoutend; |
output shift_fifo, hold_fifo, en_infifo, en_outfifo; |
output lastdataout, evalerror; |
|
reg active_sc, active_kes, active_csee; |
reg ready, decode_fail, evalsynd, holdsynd, errfound; |
reg shift_fifo, hold_fifo, en_infifo, en_outfifo; |
reg encntdataout, encntdatain; |
reg [4:0] cntdatain, cntdataout; |
reg dataoutstart, dataoutend; |
reg datainfinish; |
wire lastdataout; |
|
parameter [3:0] st1_0=0, st1_1=1, st1_2=2, st1_3=3, st1_4=4, st1_5=5, |
st1_6=6, st1_7=7, st1_8=8, st1_9=9, st1_10=10, |
st1_11=11, st1_12=12, st1_13=13, st1_14=14; |
reg [3:0] state1, nxt_state1; |
|
parameter [3:0] st2_0=0, st2_1=1, st2_2=2, st2_3=3, st2_4=4, st2_5=5, |
st2_6=6, st2_7=7, st2_8=8, st2_9=9, st2_10=10, |
st2_11=11; |
reg [3:0] state2, nxt_state2; |
|
//***************************************************// |
// FSM 1 // |
//***************************************************// |
always@(posedge clock1 or negedge reset) |
begin |
if(~reset) |
state1 = st1_0; |
else |
state1 = nxt_state1; |
end |
|
always@(state1 or start or rootcntr or lambda_degree or errdetect |
or datainfinish or finish_kes or dataoutend) |
begin |
case(state1) |
st1_0 : begin |
if(start) |
nxt_state1 = st1_1; |
else |
nxt_state1 = st1_0; |
end |
st1_1 : nxt_state1 = st1_2; |
st1_2 : begin |
if(datainfinish) |
nxt_state1 = st1_3; |
else |
nxt_state1 = st1_2; |
end |
st1_3 : begin |
if(errdetect) |
nxt_state1 = st1_4; |
else |
nxt_state1 = st1_12; |
end |
st1_4 : nxt_state1 = st1_5; |
st1_5 : begin |
if(finish_kes) |
nxt_state1 = st1_6; |
else |
nxt_state1 = st1_5; |
end |
st1_6 : nxt_state1 = st1_7; |
st1_7 : begin |
if((~start)&&(~dataoutend)) |
nxt_state1 = st1_7; |
else if(dataoutend) |
begin |
if(lambda_degree == rootcntr) |
nxt_state1 = st1_0; |
else |
nxt_state1 = st1_10; |
end |
else |
nxt_state1 = st1_8; |
end |
st1_8 : begin |
if(dataoutend) |
begin |
if(lambda_degree == rootcntr) |
nxt_state1 = st1_2; |
else |
nxt_state1 = st1_11; |
end |
else |
nxt_state1 = st1_9; |
end |
st1_9 : begin |
if(dataoutend) |
begin |
if(lambda_degree == rootcntr) |
nxt_state1 = st1_2; |
else |
nxt_state1 = st1_11; |
end |
else |
nxt_state1 = st1_9; |
end |
st1_10: begin |
if(start) |
nxt_state1 = st1_1; |
else |
nxt_state1 = st1_0; |
end |
st1_11: begin |
if(datainfinish) |
nxt_state1 = st1_3; |
else |
nxt_state1 = st1_2; |
end |
st1_12: begin |
if((~start)&&(~dataoutend)) |
nxt_state1 = st1_12; |
else if(dataoutend) |
nxt_state1 = st1_0; |
else |
nxt_state1 = st1_13; |
end |
st1_13: begin |
if(dataoutend) |
nxt_state1 = st1_2; |
else |
nxt_state1 = st1_14; |
end |
st1_14: begin |
if(dataoutend) |
nxt_state1 = st1_2; |
else |
nxt_state1 = st1_14; |
end |
default: nxt_state1 = st1_0; |
endcase |
end |
|
// Output logic of FSM1 // |
always@(state1) |
begin |
case(state1) |
st1_0 :begin |
ready = 1; |
active_sc = 0; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 0; |
end |
st1_1 :begin |
ready = 1; |
active_sc = 1; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 0; |
end |
st1_2 :begin |
ready = 1; |
active_sc = 0; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 0; |
end |
st1_3 :begin |
ready = 0; |
active_sc = 0; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 1; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 0; |
end |
st1_4 :begin |
ready = 0; |
active_sc = 0; |
active_kes = 1; |
active_csee = 0; |
evalsynd = 0; |
errfound = 1; |
decode_fail = 0; |
en_outfifo = 0; |
end |
st1_5 :begin |
ready = 0; |
active_sc = 0; |
active_kes = 1; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 0; |
end |
st1_6 :begin |
ready = 0; |
active_sc = 0; |
active_kes = 1; |
active_csee = 1; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 0; |
end |
st1_7 :begin |
ready = 1; |
active_sc = 0; |
active_kes = 1; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 1; |
end |
st1_8 :begin |
ready = 1; |
active_sc = 1; |
active_kes = 1; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 1; |
end |
st1_9 :begin |
ready = 1; |
active_sc = 0; |
active_kes = 1; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 1; |
end |
st1_10:begin |
ready = 1; |
active_sc = 0; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 1; |
en_outfifo = 0; |
end |
st1_11:begin |
ready = 1; |
active_sc = 0; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 1; |
en_outfifo = 0; |
end |
st1_12:begin |
ready = 1; |
active_sc = 0; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 1; |
end |
st1_13:begin |
ready = 1; |
active_sc = 1; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 1; |
end |
st1_14:begin |
ready = 1; |
active_sc = 0; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 1; |
end |
default:begin |
ready = 1; |
active_sc = 0; |
active_kes = 0; |
active_csee = 0; |
evalsynd = 0; |
errfound = 0; |
decode_fail = 0; |
en_outfifo = 0; |
end |
endcase |
end |
|
//****************************************// |
// FSM 2 // |
//****************************************// |
always@(posedge clock2 or negedge reset) |
begin |
if(~reset) |
state2 = st2_0; |
else |
state2 = nxt_state2; |
end |
|
always@(state2 or active_sc or cntdatain or lastdataout or en_outfifo) |
begin |
case(state2) |
st2_0 : begin |
if(active_sc) |
nxt_state2 = st2_1; |
else |
nxt_state2 = st2_0; |
end |
st2_1 : begin |
if(cntdatain == 5'b11110) |
nxt_state2 = st2_2; |
else |
nxt_state2 = st2_1; |
end |
st2_2 : nxt_state2 = st2_3; |
st2_3 : begin |
if(en_outfifo) |
nxt_state2 = st2_4; |
else |
nxt_state2 = st2_3; |
end |
st2_4 : begin |
if(active_sc) |
nxt_state2 = st2_8; |
else |
nxt_state2 = st2_5; |
end |
st2_5 : begin |
if(active_sc) |
nxt_state2 = st2_9; |
else |
nxt_state2 = st2_6; |
end |
st2_6 : begin |
if(active_sc) |
nxt_state2 = st2_9; |
else if((lastdataout) && (~active_sc)) |
nxt_state2 = st2_7; |
else |
nxt_state2 = st2_6; |
end |
st2_7 : begin |
if(active_sc) |
nxt_state2 = st2_1; |
else |
nxt_state2 = st2_0; |
end |
st2_8 : nxt_state2 = st2_9; |
st2_9 : begin |
if((lastdataout) && (cntdatain==5'b11110)) |
nxt_state2 = st2_10; |
else if(lastdataout) |
nxt_state2 = st2_11; |
else |
nxt_state2 = st2_9; |
end |
st2_10: nxt_state2 = st2_3; |
st2_11: begin |
if(cntdatain==5'b11110) |
nxt_state2 = st2_2; |
else |
nxt_state2 = st2_1; |
end |
default: nxt_state2 = st2_0; |
endcase |
end |
|
// Output logic of FSM 2 // |
always@(state2) |
begin |
case(state2) |
st2_0 : begin |
dataoutstart = 0; |
dataoutend = 0; |
shift_fifo = 0; |
hold_fifo = 0; |
en_infifo = 0; |
encntdatain = 0; |
encntdataout = 0; |
holdsynd = 0; |
datainfinish = 0; |
end |
st2_1 : begin |
dataoutstart = 0; |
dataoutend = 0; |
shift_fifo = 1; |
hold_fifo = 0; |
en_infifo = 1; |
encntdatain = 1; |
encntdataout = 0; |
holdsynd = 0; |
datainfinish = 0; |
end |
st2_2 : begin |
dataoutstart = 0; |
dataoutend = 0; |
shift_fifo = 1; |
hold_fifo = 0; |
en_infifo = 1; |
encntdatain = 0; |
encntdataout = 0; |
holdsynd = 0; |
datainfinish = 1; |
end |
st2_3 : begin |
dataoutstart = 0; |
dataoutend = 0; |
shift_fifo = 0; |
hold_fifo = 1; |
en_infifo = 0; |
encntdatain = 0; |
encntdataout = 0; |
holdsynd = 1; |
datainfinish = 0; |
end |
st2_4 : begin |
dataoutstart = 0; |
dataoutend = 0; |
shift_fifo = 0; |
hold_fifo = 1; |
en_infifo = 0; |
encntdatain = 0; |
encntdataout = 1; |
holdsynd = 0; |
datainfinish = 0; |
end |
st2_5 : begin |
dataoutstart = 1; |
dataoutend = 0; |
shift_fifo = 1; |
hold_fifo = 0; |
en_infifo = 0; |
encntdatain = 0; |
encntdataout = 1; |
holdsynd = 0; |
datainfinish = 0; |
end |
st2_6 : begin |
dataoutstart = 0; |
dataoutend = 0; |
shift_fifo = 1; |
hold_fifo = 0; |
en_infifo = 0; |
encntdatain = 0; |
encntdataout = 1; |
holdsynd = 0; |
datainfinish = 0; |
end |
st2_7 : begin |
dataoutstart = 0; |
dataoutend = 1; |
shift_fifo = 0; |
hold_fifo = 0; |
en_infifo = 0; |
encntdatain = 0; |
encntdataout = 0; |
holdsynd = 0; |
datainfinish = 0; |
end |
st2_8 : begin |
dataoutstart = 1; |
dataoutend = 0; |
shift_fifo = 1; |
hold_fifo = 0; |
en_infifo = 1; |
encntdatain = 1; |
encntdataout = 1; |
holdsynd = 0; |
datainfinish = 0; |
end |
st2_9 : begin |
dataoutstart = 0; |
dataoutend = 0; |
shift_fifo = 1; |
hold_fifo = 0; |
en_infifo = 1; |
encntdatain = 1; |
encntdataout = 1; |
holdsynd = 0; |
datainfinish = 0; |
end |
st2_10: begin |
dataoutstart = 0; |
dataoutend = 1; |
shift_fifo = 1; |
hold_fifo = 0; |
en_infifo = 1; |
encntdatain = 0; |
encntdataout = 0; |
holdsynd = 0; |
datainfinish = 1; |
end |
st2_11: begin |
dataoutstart = 0; |
dataoutend = 1; |
shift_fifo = 1; |
hold_fifo = 0; |
en_infifo = 1; |
encntdatain = 1; |
encntdataout = 0; |
holdsynd = 0; |
datainfinish = 0; |
end |
default: begin |
dataoutstart = 0; |
dataoutend = 0; |
shift_fifo = 0; |
hold_fifo = 0; |
en_infifo = 0; |
encntdatain = 0; |
encntdataout = 0; |
holdsynd = 0; |
datainfinish = 0; |
end |
endcase |
end |
|
|
//*********************// |
// Counter for dataout // |
always@(posedge clock1) |
begin |
if(encntdataout) |
cntdataout = cntdataout + 1; |
else |
cntdataout = 5'b0; |
end |
|
// Counter for datain // |
always@(posedge clock1) |
begin |
if(encntdatain) |
cntdatain = cntdatain + 1; |
else |
cntdatain = 5'b0; |
end |
|
// lastdataout is 1 if cntdataout = 5'b11111 // |
assign lastdataout = cntdataout[4] & (cntdataout[3]&cntdataout[2]) & |
(cntdataout[1]&cntdataout[0]); |
|
assign evalerror = encntdataout; |
|
endmodule |
/tags/rel-1_0/README.TXT
0,0 → 1,43
++++++++++++++++++++++++++ |
RS Decoder (31,19,6) v1.1 |
++++++++++++++++++++++++++ |
|
This project consists of 8 verilog files including a testbench file. |
The files are: |
- RSDecoder.v : contains description of top module of the decoder. It combines |
5 modules of typical RS Decoder building blocks. |
- scblock.v : contains description of the SC (Syndrome Computation) block and its |
submodules. |
- kesblock.v : KES (Key Equation Solver) block and its submodules. |
- cseeblock.v : CSEE (Chien Search and Error Evaluator) block and parallel |
invers multiplier module. CSEE is the only block in the decoder |
that use invers multiplier to compute error magnitude using Fourney |
Formula. |
- controller.v : describes controller module. It consists of 2 FSMs and 2 counters. |
- fifo_register.v : a FIFO register consists of 31 registers to store received word and |
a register to synchronize outputted data with CSEE block. |
- common_modules.v: this file contains basic modules that used by other higher modules. |
It behaves like a library for the project. |
- testbench.v : the testbench contains 3 different received word vectors. First |
received word contains no error symbol. Second word contains 6 error |
symbols and the last word contains 8 error symbols. |
|
Limitations in this version: |
Despite its high data rates, the decoder has some limitations that must be considered. |
- It flags decoding failure at the end of outputted word. So, other block outside the |
decoder cannot differentiate between uncorrected word and corrected word until it |
receive decoding failure flag at the end of the word. |
- Decoding failure is detected when degree of error location polynomial and |
number of its roots is not equal. It means the error location polynomial doesn't |
have roots in the underlying GF(2^5). To determine the roots, decoder must activate |
CSEE block first. Hence, decoding failure is detected after all elements in |
GF(2^5) have been evaluated. |
- Uncorrectable word still have to be summed with wrong error values. Because decoding |
failure is detected at the end of word, there is no other mechanism to solve |
the problem, unless decoder start to output the word after all GF(2^5) elements |
has been evaluated. |
Hopefully, in next version, limitations above can be solved. |
|
|
Rudy Dwi Putra |
rudy.dp@gmail.com |
/tags/rel-1_0/fifo_register.v
0,0 → 1,70
//********************************************************// |
// FIFO Register stores 31 recieved word symbols // |
//********************************************************// |
module fifo_register(clock1, clock2, shift_fifo, hold_fifo, |
en_outfifo, en_infifo, datain, dataout); |
|
input clock1, clock2; |
input shift_fifo, hold_fifo, en_outfifo, en_infifo; |
input [4:0] datain; |
output [4:0] dataout; |
|
wire [4:0] outreg0, outreg1, outreg2, outreg3, outreg4, |
outreg5, outreg6, outreg7, outreg8, outreg9, |
outreg10, outreg11, outreg12, outreg13, outreg14, |
outreg15, outreg16, outreg17, outreg18, outreg19, |
outreg20, outreg21, outreg22, outreg23, outreg24, |
outreg25, outreg26, outreg27, outreg28, outreg29, |
outreg30; |
wire [4:0] inputzero; |
reg [4:0] outmux; |
|
assign inputzero = 5'b0; |
|
always@(en_infifo or inputzero or datain) |
begin |
case(en_infifo) |
0 : outmux = inputzero; |
1 : outmux = datain; |
endcase |
end |
|
// 31 registers storing received words operate on clock1 // |
register5_wlh Reg0(outmux, outreg0, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg1(outreg0, outreg1, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg2(outreg1, outreg2, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg3(outreg2, outreg3, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg4(outreg3, outreg4, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg5(outreg4, outreg5, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg6(outreg5, outreg6, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg7(outreg6, outreg7, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg8(outreg7, outreg8, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg9(outreg8, outreg9, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg10(outreg9, outreg10, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg11(outreg10, outreg11, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg12(outreg11, outreg12, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg13(outreg12, outreg13, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg14(outreg13, outreg14, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg15(outreg14, outreg15, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg16(outreg15, outreg16, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg17(outreg16, outreg17, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg18(outreg17, outreg18, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg19(outreg18, outreg19, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg20(outreg19, outreg20, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg21(outreg20, outreg21, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg22(outreg21, outreg22, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg23(outreg22, outreg23, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg24(outreg23, outreg24, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg25(outreg24, outreg25, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg26(outreg25, outreg26, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg27(outreg26, outreg27, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg28(outreg27, outreg28, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg29(outreg28, outreg29, shift_fifo, hold_fifo, clock1); |
register5_wlh Reg30(outreg29, outreg30, shift_fifo, hold_fifo, clock1); |
|
// Output register operates on clock2 to synchronize with // |
// output of CSEE. // |
register5_wl outreg(outreg30, dataout, clock2, en_outfifo); |
|
endmodule |
|
/tags/rel-1_0/RSDecoder.v
0,0 → 1,90
///*************************************************************/// |
/// /// |
/// Reed-Solomon Decoder (31,19,6) /// |
/// /// |
/// /// |
/// Author : Rudy Dwi Putra /// |
/// rudy.dp@gmail.com /// |
/// /// |
///*************************************************************/// |
/// /// |
/// Copyright (C) 2006 Rudy Dwi Putra /// |
/// rudy.dp@gmail.com /// |
/// /// |
/// This source file may be used and distributed without /// |
/// restriction provided that this copyright statement is not /// |
/// removed from the file and that any derivative work contains /// |
/// the original copyright notice and the associated disclaimer./// |
/// /// |
/// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY /// |
/// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED /// |
/// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS /// |
/// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR /// |
/// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, /// |
/// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES /// |
/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE /// |
/// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR /// |
/// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF /// |
/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT /// |
/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT /// |
/// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE /// |
/// POSSIBILITY OF SUCH DAMAGE. /// |
/// /// |
///*************************************************************/// |
|
|
module RSDecoder(recword, start, clock1, clock2, reset, ready, |
errfound, decode_fail, dataoutstart, dataoutend, |
corr_recword); |
|
input [4:0] recword; |
input clock1, clock2; |
input start, reset; |
output ready, decode_fail, errfound, dataoutstart, dataoutend; |
output [4:0] corr_recword; |
|
wire active_sc, active_kes, active_csee, en_sccell; |
wire evalsynd, holdsynd, evalerror, lastdataout; |
wire shift_fifo, hold_fifo, en_infifo, en_outfifo; |
wire errdetect, finish_kes; |
wire [4:0] dataout_fifo, errorvalue; |
|
wire [4:0] syndvalue0, syndvalue1, syndvalue2, syndvalue3, |
syndvalue4, syndvalue5, syndvalue6, syndvalue7, |
syndvalue8, syndvalue9, syndvalue10, syndvalue11; |
wire [4:0] lambda0, lambda1, lambda2, lambda3, lambda4, lambda5, |
lambda6; |
wire [4:0] homega0, homega1, homega2, homega3, homega4, homega5; |
wire [2:0] rootcntr, lambda_degree; |
|
//****************************// |
assign en_sccell = shift_fifo; |
|
SCblock SCblock(recword, clock1, clock2, active_sc, reset, syndvalue0, |
syndvalue1, syndvalue2, syndvalue3, syndvalue4, |
syndvalue5, syndvalue6, syndvalue7, syndvalue8, |
syndvalue9, syndvalue10, syndvalue11, errdetect, |
en_sccell, evalsynd, holdsynd); |
KES_block KESblock(active_kes, clock1, clock2, reset, syndvalue0, syndvalue1, syndvalue2, syndvalue3, syndvalue4, syndvalue5, syndvalue6, |
syndvalue7, syndvalue8, syndvalue9, syndvalue10, syndvalue11, |
lambda0, lambda1, lambda2, lambda3, lambda4, lambda5, |
lambda6, homega0, homega1, homega2, homega3, homega4, |
homega5, lambda_degree, finish_kes); |
CSEEblock CSEEblock(lambda0, lambda1, lambda2, lambda3, lambda4, |
lambda5, lambda6, homega0, homega1, homega2, |
homega3, homega4, homega5, errorvalue, clock1, |
clock2, active_csee, reset, lastdataout, evalerror, |
en_outfifo, rootcntr); |
MainControl controller(start, reset, clock1, clock2, finish_kes, |
errdetect, rootcntr, lambda_degree, active_sc, |
active_kes, active_csee, evalsynd, holdsynd, |
errfound, decode_fail, ready, dataoutstart, dataoutend, |
shift_fifo, hold_fifo, en_infifo, en_outfifo, |
lastdataout, evalerror); |
fifo_register fiforeg(clock1, clock2, shift_fifo, hold_fifo, |
en_outfifo, en_infifo, recword, dataout_fifo); |
|
// Received word correction// |
gfadder adder(errorvalue, dataout_fifo, corr_recword); |
|
endmodule |
/tags/rel-1_0/cseeblock.v
0,0 → 1,404
//***************************************************************// |
// Chien Search and Error Evaluator (CSEE) block find // |
// error location (Xi) while determine its error magnitude (Yi). // |
// This CSEE block implement Chien search algorithm to find // |
// location of an error and Fourney Formula to compute the error // |
// error value. Error value will be outputted serially and has // |
// to be synchronous with output of FIFO Register. // |
//***************************************************************// |
|
module CSEEblock(lambda0, lambda1, lambda2, lambda3, lambda4, |
lambda5, lambda6, homega0, homega1, homega2, |
homega3, homega4, homega5, errorvalue, clock1, |
clock2, active_csee, reset, lastdataout, evalerror, |
en_outfifo, rootcntr); |
|
input [4:0] lambda0, lambda1, lambda2, lambda3, lambda4, |
lambda5, lambda6; |
input [4:0] homega0, homega1, homega2, homega3, homega4, homega5; |
input clock1, clock2, active_csee, reset; |
input lastdataout, evalerror, en_outfifo; |
output [4:0] errorvalue; |
output [2:0] rootcntr; |
|
wire [4:0] cs0_out, cs1_out, cs2_out, cs3_out, cs4_out, cs5_out, |
cs6_out; |
wire [4:0] fn0_out, fn1_out, fn2_out, fn3_out, fn4_out, fn5_out; |
wire [4:0] oddlambda, evenlambda, lambdaval; |
wire [4:0] omegaval, fourney_out, inv_oddlambda; |
wire zerodetect; |
wire [4:0] andtree_out; |
reg load; |
reg enrootcnt; |
reg [2:0] rootcntr; |
|
parameter st0=0, st1=1; |
reg state, nxt_state; |
|
//*****// |
// FSM // |
//*****// |
always@(posedge clock2 or negedge reset) |
begin |
if(~reset) |
state = st0; |
else |
state = nxt_state; |
end |
|
always@(state or active_csee or lastdataout) |
begin |
case(state) |
st0 : begin |
if(active_csee) |
nxt_state = st1; |
else |
nxt_state = st0; |
end |
st1 : begin |
if(lastdataout) |
nxt_state = st0; |
else |
nxt_state = st1; |
end |
default: nxt_state = st0; |
endcase |
end |
|
always@(state) |
begin |
case(state) |
st0 : begin |
load = 0; |
enrootcnt = 0; |
end |
st1 : begin |
load = 1; |
enrootcnt = 1; |
end |
default: begin |
load = 0; |
enrootcnt = 0; |
end |
endcase |
end |
|
//********************************// |
// Counter for roots of lambda(x) // |
// with synchronous hold // |
//********************************// |
always@(posedge clock2) |
begin |
if(enrootcnt) |
begin |
if(zerodetect) |
rootcntr <= rootcntr + 1; |
else |
rootcntr <= rootcntr; |
end |
else |
rootcntr <= 3'b0; |
end |
|
|
//*******************// |
// Chien Seach block // |
//*******************// |
degree0_cell cs0_cell(lambda0, cs0_out, clock1, load, evalerror); |
degree1_cell cs1_cell(lambda1, cs1_out, clock1, load, evalerror); |
degree2_cell cs2_cell(lambda2, cs2_out, clock1, load, evalerror); |
degree3_cell cs3_cell(lambda3, cs3_out, clock1, load, evalerror); |
degree4_cell cs4_cell(lambda4, cs4_out, clock1, load, evalerror); |
degree5_cell cs5_cell(lambda5, cs5_out, clock1, load, evalerror); |
degree6_cell cs6_cell(lambda6, cs6_out, clock1, load, evalerror); |
|
assign oddlambda = cs1_out ^ cs3_out ^ cs5_out; |
assign evenlambda = (cs0_out ^ cs2_out) ^ (cs4_out ^ cs6_out); |
assign lambdaval = oddlambda ^ evenlambda; |
|
//*****************************************// |
// Error Evaluator (Fourney Formula) block // |
//*****************************************// |
degree0_cell fn0_cell(homega0, fn0_out, clock1, load, evalerror); |
degree1_cell fn1_cell(homega1, fn1_out, clock1, load, evalerror); |
degree2_cell fn2_cell(homega2, fn2_out, clock1, load, evalerror); |
degree3_cell fn3_cell(homega3, fn3_out, clock1, load, evalerror); |
degree4_cell fn4_cell(homega4, fn4_out, clock1, load, evalerror); |
degree5_cell fn5_cell(homega5, fn5_out, clock1, load, evalerror); |
|
assign omegaval = (fn0_out ^ fn1_out) ^ (fn2_out ^ fn3_out) ^ |
(fn4_out ^ fn5_out); |
|
inverscomb invers(oddlambda, inv_oddlambda); |
lcpmult multiplier(inv_oddlambda, omegaval, fourney_out); |
|
//*****************************// |
// Zero detect and error value // |
//*****************************// |
assign zerodetect = ~((lambdaval[0]|lambdaval[1]) | |
(lambdaval[2]|lambdaval[3]) | lambdaval[4]); |
assign andtree_out[0] = fourney_out[0] & zerodetect; |
assign andtree_out[1] = fourney_out[1] & zerodetect; |
assign andtree_out[2] = fourney_out[2] & zerodetect; |
assign andtree_out[3] = fourney_out[3] & zerodetect; |
assign andtree_out[4] = fourney_out[4] & zerodetect; |
|
//assign errorvalue = andtree_out; |
register5_wl erroreg(andtree_out, errorvalue, clock2, en_outfifo); |
|
endmodule |
|
|
//******************************************************// |
// Modul-modul chien search cell dibentuk dgn perkalian // |
|
//***********************************************// |
// Module for terms whose degree is zero // |
//***********************************************// |
module degree0_cell(in, out, clock, load, compute); |
|
input [4:0] in; |
output [4:0] out; |
input clock, compute, load; |
wire [4:0] outmux, outreg; |
|
register5_wl register(outmux, outreg, clock, load); |
mux2_to_1 multiplex(in, outreg, outmux, compute); |
assign out = outreg; |
|
endmodule |
|
|
//********************************************************// |
// Module that computes term with degree one. // |
// Constructed by a variable-constant multiplier with // |
// alpha^1 as constant. // |
//********************************************************// |
module degree1_cell(in, out, clock, load, compute); |
|
input [4:0] in; |
output [4:0] out; |
input clock, load, compute; |
wire [4:0] outmux; |
wire [0:4] outmult, outreg; |
|
register5_wl register(outmux, outreg, clock, load); |
mux2_to_1 multiplexer(in, outmult, outmux, compute); |
|
//Multipy variable-alpha^1 |
assign outmult[0] = outreg[4]; |
assign outmult[1] = outreg[0]; |
assign outmult[2] = outreg[1] ^ outreg[4]; |
assign outmult[3] = outreg[2]; |
assign outmult[4] = outreg[3]; |
|
assign out = outreg; |
|
endmodule |
|
|
//********************************************************// |
// Module that computes term with degree two. |
// Constructed by a variable-constant multiplier with |
// alpha^2 as constant. // |
//********************************************************// |
module degree2_cell(in, out, clock, load, compute); |
|
input [4:0] in; |
output [4:0] out; |
input clock, load, compute; |
wire [4:0] outmux; |
wire [0:4] outmult, outreg; |
|
register5_wl register(outmux, outreg, clock, load); |
mux2_to_1 multiplexer(in, outmult, outmux, compute); |
|
//Multipy variable-alpha^2 |
assign outmult[0] = outreg[3]; |
assign outmult[1] = outreg[4]; |
assign outmult[2] = outreg[0] ^ outreg[3]; |
assign outmult[3] = outreg[1] ^ outreg[4]; |
assign outmult[4] = outreg[2]; |
|
assign out = outreg; |
|
endmodule |
|
//********************************************************// |
// Module that computes term with degree three. // |
// Constructed by a variable-constant multiplier with // |
// alpha^3 as constant. // |
//********************************************************// |
module degree3_cell(in, out, clock, load, compute); |
|
input [4:0] in; |
output [4:0] out; |
input clock, load, compute; |
wire [4:0] outmux; |
wire [0:4] outmult, outreg; |
|
register5_wl register(outmux, outreg, clock, load); |
mux2_to_1 multiplexer(in, outmult, outmux, compute); |
|
//Multipy variable-alpha^3 |
assign outmult[0] = outreg[2]; |
assign outmult[1] = outreg[3]; |
assign outmult[2] = outreg[2] ^ outreg[4]; |
assign outmult[3] = outreg[0] ^ outreg[3]; |
assign outmult[4] = outreg[1] ^ outreg[4]; |
|
assign out = outreg; |
|
endmodule |
|
|
//********************************************************// |
// Module that computes term with degree four. // |
// Constructed by a variable-constant multiplier with // |
// alpha^4 as constant. // |
//********************************************************// |
module degree4_cell(in, out, clock, load, compute); |
|
input [4:0] in; |
output [4:0] out; |
input clock, load, compute; |
wire [4:0] outmux; |
wire [0:4] outmult, outreg; |
|
register5_wl register(outmux, outreg, clock, load); |
mux2_to_1 multiplexer(in, outmult, outmux, compute); |
|
//Multipy variable-alpha^4 |
assign outmult[0] = outreg[1] ^ outreg[4]; |
assign outmult[1] = outreg[2]; |
assign outmult[2] = outreg[1] ^ outreg[3] ^ outreg[4]; |
assign outmult[3] = outreg[2] ^ outreg[4]; |
assign outmult[4] = outreg[0] ^ outreg[3]; |
|
assign out = outreg; |
|
endmodule |
|
//********************************************************// |
// Module that computes term with degree five. // |
// Constructed by a variable-constant multiplier with // |
// alpha^5 as constant. // |
//********************************************************// |
module degree5_cell(in, out, clock, load, compute); |
|
input [4:0] in; |
output [4:0] out; |
input clock, load, compute; |
wire [4:0] outmux; |
wire [0:4] outmult, outreg; |
|
register5_wl register(outmux, outreg, clock, load); |
mux2_to_1 multiplexer(in, outmult, outmux, compute); |
|
//Multipy variable-alpha^5 |
assign outmult[0] = outreg[0] ^ outreg[3]; |
assign outmult[1] = outreg[1] ^ outreg[4]; |
assign outmult[2] = outreg[0] ^ outreg[2] ^ outreg[3]; |
assign outmult[3] = outreg[1] ^ outreg[3] ^ outreg[4]; |
assign outmult[4] = outreg[2] ^ outreg[4]; |
|
assign out = outreg; |
|
endmodule |
|
//********************************************************// |
// Module that computes term with degree six. // |
// Constructed by a variable-constant multiplier with // |
// alpha^6 as constant. // |
//********************************************************// |
module degree6_cell(in, out, clock, load, compute); |
|
input [4:0] in; |
output [4:0] out; |
input clock, load, compute; |
wire [4:0] outmux; |
wire [0:4] outmult, outreg; |
|
register5_wl register(outmux, outreg, clock, load); |
mux2_to_1 multiplexer(in, outmult, outmux, compute); |
|
//Multipy variable-alpha^6 |
assign outmult[0] = outreg[2] ^ outreg[4]; |
assign outmult[1] = outreg[0] ^ outreg[3]; |
assign outmult[2] = outreg[1] ^ outreg[2]; |
assign outmult[3] = outreg[0] ^ outreg[2] ^ outreg[3]; |
assign outmult[4] = outreg[1] ^ outreg[3] ^ outreg[4]; |
|
assign out = outreg; |
|
endmodule |
|
|
//***********************************************************// |
// Invers Multiplication module for GF(2^5) is formed by AND // |
// and XOR gates. This module is derived directly from // |
// Fermat Theorem, which state that // |
// beta^(-1) = beta^2.beta^(2^2).beta^(2^3).beta^(2^4), // |
// for beta member of GF(2^5). // |
// Note: this module is only used in CSEE block // |
//***********************************************************// |
module inverscomb(in, out); |
|
input [0:4] in; |
output [0:4] out; |
|
//form product consists of AND gates |
wire p0, p1, p2, p3, p4 , p5 , p6, p7, p8, p9, |
p10, p11, p12, p13, p14, p15, p16, p17, p18, |
p19, p20, p21, p22, p23, p24; |
//form intermediate sum of the product that can be reused |
wire s0, s1, s2, s3, s4, s5, s6; |
|
//form intermediate sum of product that is only used by single function |
wire t0, t1, t2; |
|
assign p0 = in[0]&in[1]; |
assign p1 = in[0]&in[2]; |
assign p2 = in[0]&in[3]; |
assign p3 = in[0]&in[4]; |
assign p4 = in[1]&in[2]; |
assign p5 = in[1]&in[3]; |
assign p6 = in[1]&in[4]; |
assign p7 = in[2]&in[4]; |
assign p8 = in[3]&in[4]; |
assign p9 = in[2]&in[3]; |
assign p10 = p0&in[2]; |
assign p11 = p0&in[4]; |
assign p12 = p2&in[4]; |
assign p13 = p9&in[0]; |
assign p14 = p4&in[3]; |
assign p15 = p8&in[2]; |
assign p16 = p7&in[1]; |
assign p17 = p2&in[1]; |
assign p18 = p3&in[2]; |
assign p19 = p6&in[3]; |
assign p20 = p4&p8; |
assign p21 = p1&p5; |
assign p22 = p3&p5; |
assign p23 = p2&p7; |
assign p24 = p1&p6; |
|
assign s0 = p1 ^ p15; |
assign s1 = ((p6 ^ p12) ^ p14); |
assign s2 = (in[4] ^ p0) ^ p21; |
assign s3 = (in[1] ^ in[3]) ^ (p2 ^ p3) ^ (p24 ^ p10); |
assign s4 = (p4 ^ p5) ^ (p20 ^ p7) ^ p17; |
assign s5 = (in[2] ^ p5) ^ (p22 ^ p23); |
assign s6 = p11 ^ p20; |
|
assign t0 = (in[0] ^ p2) ^ (p4 ^ p10); |
assign t1 = (in[3] ^ p0) ^ p24; |
assign t2 = p19 ^ p23; |
|
assign out[0] = ((s0 ^ s1) ^ (s2 ^ s5)) ^ ((s6 ^ p13) ^ t0); |
assign out[1] = ((s0 ^ s1) ^ s2) ^ (s3 ^ (s6 ^ p16)); |
assign out[2] = (s0 ^ s4) ^ ((p13 ^ p8) ^ t1); |
assign out[3] = ((s0 ^ s1) ^ (s2 ^ s5)) ^ ((p16 ^ p8) ^ (p9 ^ p18) ^ p7); |
assign out[4] = (s0 ^ s1) ^ (s3 ^ s4) ^ (p9 ^ t2); |
|
endmodule |