blob: 30ba5317a6682fa6872e7943696d6f214b18584b [file] [log] [blame]
// This module compares two bitstreams and automatically determines their
// offset. This is done by iteratively changing bit delay for I_DAT_REF
// every time the number of errors exceeds ERROR_COUNT. The output O_ERROR
// signal is high for at least ERROR_HOLD cycles.
`default_nettype none
// ============================================================================
module comparator #
(
parameter ERROR_COUNT = 8,
parameter ERROR_HOLD = 2500000
)
(
input wire CLK,
input wire RST,
input wire I_DAT_REF,
input wire I_DAT_IOB,
output wire O_ERROR
);
// ============================================================================
// Data latch
reg [2:0] i_dat_ref_sr;
reg [2:0] i_dat_iob_sr;
always @(posedge CLK)
i_dat_ref_sr <= (i_dat_ref_sr << 1) | I_DAT_REF;
always @(posedge CLK)
i_dat_iob_sr <= (i_dat_iob_sr << 1) | I_DAT_IOB;
wire i_dat_ref = i_dat_ref_sr[2];
wire i_dat_iob = i_dat_iob_sr[2];
// ============================================================================
// Shift register for reference data, shift strobe generator.
reg [31:0] sreg;
reg [ 4:0] sreg_sel;
wire sreg_dat;
reg sreg_sh;
always @(posedge CLK)
sreg <= (sreg << 1) | i_dat_ref;
always @(posedge CLK)
if (RST)
sreg_sel <= 0;
else if(sreg_sh)
sreg_sel <= sreg_sel + 1;
assign sreg_dat = sreg[sreg_sel];
// ============================================================================
// Comparator and error counter
wire cmp_err;
reg [31:0] err_cnt;
assign cmp_err = sreg_dat ^ i_dat_iob;
always @(posedge CLK)
if (RST)
err_cnt <= 0;
else if(sreg_sh)
err_cnt <= 0;
else if(cmp_err)
err_cnt <= err_cnt + 1;
always @(posedge CLK)
if (RST)
sreg_sh <= 0;
else if(~sreg_sh && (err_cnt == ERROR_COUNT))
sreg_sh <= 1;
else
sreg_sh <= 0;
// ============================================================================
// Output generator
reg [24:0] o_cnt;
always @(posedge CLK)
if (RST)
o_cnt <= -1;
else if (cmp_err)
o_cnt <= ERROR_HOLD - 2;
else if (~o_cnt[24])
o_cnt <= o_cnt - 1;
assign O_ERROR = !o_cnt[24];
endmodule