mirror of https://github.com/openXC7/prjxray.git
94 lines
2.1 KiB
Verilog
94 lines
2.1 KiB
Verilog
// 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
|