blob: 11a6cb8dc66649f92c4e2d1232b5e1398678d95f [file] [log] [blame] [edit]
module srl_shift_tester #
(
parameter [511:0] ROM_CONTENT = 512'h0833D855BF064C540DFD9FFFB51E402AC1839A048A68620BD94EB15E67C8FE9DDA32A47EA170107BB10665E6A59D3CE2359205CDFD5E598E490BBA776C334DB9,
parameter SRL_LENGTH = 32,
parameter FIXED_DELAY = 1
)
(
input wire clk,
input wire rst,
input wire ce,
output reg srl_sh,
output wire [$clog2(SRL_LENGTH)-1:0] srl_a,
output wire srl_d,
input wire srl_q,
output reg error
);
// ============================================================================
// ROM
wire [8:0] rom_adr;
wire rom_dat;
ROM #(.CONTENT(ROM_CONTENT)) rom
(
.clk (clk),
.adr (rom_adr),
.dat (rom_dat)
);
// ============================================================================
// Control
reg [$clog2(SRL_LENGTH)-1:0] delay;
reg [1:0] phase;
initial phase <= 0;
always @(posedge clk)
if (rst)
phase <= 2'b11;
else if (ce)
phase <= 2'd0;
else if (!phase[1])
phase <= phase + 1;
// Data fetch
reg rom_dat_1 = 1'b0;
reg rom_dat_2 = 1'b0;
assign rom_adr = (phase == 2'd0) ? rom_adr_1 : rom_adr_2;
always @(posedge clk)
if (phase == 2'd0)
rom_dat_1 <= rom_dat;
always @(posedge clk)
if (phase == 2'd1)
rom_dat_2 <= rom_dat;
// Address counter
reg [8:0] rom_adr_1 = 0;
reg [8:0] rom_adr_2 = 0;
always @(posedge clk)
if (rst)
rom_adr_1 <= 0;
else if (phase == 2'd1)
rom_adr_1 <= rom_adr_1 + 1;
always @(posedge clk)
rom_adr_2 <= rom_adr_1 + delay;
// SRL control
initial srl_sh <= 1'b0;
always @(posedge clk)
if (!srl_sh) srl_sh <= (phase == 2'd0);
else srl_sh <= 0;
assign srl_a = delay;
assign srl_d = rom_dat_1;
// Delay change
wire delay_chg = (FIXED_DELAY == 0) && (phase == 2'd1 && rom_adr_1 == 9'h1FF);
initial delay <= FIXED_DELAY - 1;
always @(posedge clk)
if (rst)
delay <= FIXED_DELAY - 1;
else if (delay_chg)
delay <= (delay == (SRL_LENGTH - 1)) ? 0 : (delay + 1);
// ============================================================================
// Error check
// Check inhibit (after delay change)
reg [8:0] inh_cnt = -1;
wire check_inh = ~inh_cnt[8];
always @(posedge clk)
if (rst)
inh_cnt <= SRL_LENGTH - 1;
else if (phase == 1) begin
if (delay_chg)
inh_cnt <= SRL_LENGTH - 1;
else if(check_inh)
inh_cnt <= inh_cnt - 1;
end
// Error check
initial error <= 1'b0;
always @(posedge clk)
error <= !check_inh && (srl_q ^ rom_dat_2);
endmodule