blob: 4cef038131eddc4689383e95efc5bc52e7c46427 [file] [log] [blame]
`timescale 1ns / 1ps
/* Chien search, determines roots of a polynomial defined over a finite field */
module dch #(
parameter M = 4,
parameter P = 1
) (
input clk,
input err, /* Error was found so correct it */
input ce,
input start,
input [M-1:0] in,
output reg [M-1:0] out = 0
);
`include "bch.vh"
localparam TCQ = 1;
localparam LPOW = lpow(M, P);
wire [M-1:0] mul_out;
parallel_standard_multiplier #(M) u_mult(
.standard_in1(LPOW[M-1:0]),
.standard_in2(out ^ err),
.standard_out(mul_out)
);
always @(posedge clk)
if (start)
/* Initialize with coefficients of the error location polynomial */
out <= #TCQ in;
else if (ce)
/* Multiply by alpha^P */
out <= #TCQ mul_out;
endmodule
/*
* Tradition chien search, for each cycle, check if the
* sum of all the equations is zero, if so, this location
* is a bit error. K cycles are required.
*
* Each register is loaded with the associated syndrome
* and multiplied by alpha^i each cycle.
*/
module chien #(
parameter M = 4,
parameter K = 5,
parameter T = 3
) (
input clk,
input ce,
input start,
input [M*(T+1)-1:0] sigma,
output done,
output err
);
`include "bch.vh"
wire [M-1:0] eq;
wire [M*(T+1)-1:0] z;
wire [M*(T+1)-1:0] chien_mask;
wire [M-1:0] count;
reg busy = 0;
localparam TCQ = 1;
genvar i;
generate
/* Chien search */
for (i = 0; i <= T; i = i + 1) begin : ch
dch #(M, i) u_ch(
.clk(clk),
.err(1'b0),
.ce(ce && busy),
.start(start),
.in(sigma[i*M+:M]),
.out(z[i*M+:M])
);
end
endgenerate
lfsr_counter #(M) u_counter(
.clk(clk),
.reset(start),
.ce(busy),
.count(count)
);
assign done = busy && (count == lfsr_count(M, K));
always @(posedge clk)
busy <= #TCQ start || (busy && !done);
finite_parallel_adder #(M, T+1) u_dcheq(z, eq);
assign err = !eq;
endmodule