/*
reset...init...save.start_write.stop_write.restore.start_read(compare).stop_read.loop
error...
*/
module mem_tester(
clk,
rst_n,
led, // LED flashing or not
// SRAM signals
SRAM_DQ, // sram inout databus
SRAM_ADDR, // sram address bus
SRAM_UB_N,
SRAM_LB_N,
SRAM_WE_N, //
SRAM_CE_N, //
SRAM_OE_N //
);
parameter SRAM_DATA_SIZE = 8;
parameter SRAM_ADDR_SIZE = 19;
inout [SRAM_DATA_SIZE-1:0] SRAM_DQ;
wire [SRAM_DATA_SIZE-1:0] SRAM_DQ;
output [SRAM_ADDR_SIZE-1:0] SRAM_ADDR;
wire [SRAM_ADDR_SIZE-1:0] SRAM_ADDR;
output SRAM_UB_N,SRAM_LB_N,SRAM_WE_N,SRAM_CE_N,SRAM_OE_N;
wire SRAM_UB_N,SRAM_LB_N,SRAM_WE_N,SRAM_CE_N,SRAM_OE_N;
input clk;
input rst_n;
output led; reg led;
reg inc_pass_ctr; // increment passes counter (0000-9999 BCD)
reg inc_err_ctr; // increment errors counter (10 red binary LEDs)
reg check_in_progress; // when 1 - enables errors checking
reg [19:0] ledflash;
always @(posedge clk)
begin
if( inc_pass_ctr )
ledflash <= 20'd0;
else if( !ledflash[19] )
ledflash <= ledflash + 20'd1;
end
always @(posedge clk)
begin
led <= ledflash[19] ^ was_error;
end
reg was_error;
always @(posedge clk, negedge rst_n)
begin
if( !rst_n )
was_error <= 1'b0;
else if( inc_err_ctr )
was_error <= 1'b1;
end
reg rnd_init,rnd_save,rnd_restore; // rnd_vec_gen control
wire [SRAM_DATA_SIZE-1:0] rnd_out; // rnd_vec_gen output
rnd_vec_gen my_rnd( .clk(clk), .init(rnd_init), .next(sram_ready), .save(rnd_save), .restore(rnd_restore), .out(rnd_out) );
defparam my_rnd.OUT_SIZE = SRAM_DATA_SIZE;
defparam my_rnd.LFSR_LENGTH = 41;
defparam my_rnd.LFSR_FEEDBACK = 3;
reg sram_start,sram_rnw;
wire sram_stop,sram_ready;
wire [SRAM_DATA_SIZE-1:0] sram_rdat;
sram_control my_sram( .clk(clk), .clk2(clk), .start(sram_start), .rnw(sram_rnw), .stop(sram_stop), .ready(sram_ready),
.rdat(sram_rdat), .wdat(rnd_out),
.SRAM_DQ(SRAM_DQ), .SRAM_ADDR(SRAM_ADDR),
.SRAM_CE_N(SRAM_CE_N), .SRAM_OE_N(SRAM_OE_N), .SRAM_WE_N(SRAM_WE_N) );
defparam my_sram.SRAM_DATA_SIZE = SRAM_DATA_SIZE;
defparam my_sram.SRAM_ADDR_SIZE = SRAM_ADDR_SIZE;
// FSM states and registers
reg [3:0] curr_state,next_state;
parameter RESET = 4'h0;
parameter INIT1 = 4'h1;
parameter INIT2 = 4'h2;
parameter BEGIN_WRITE1 = 4'h3;
parameter BEGIN_WRITE2 = 4'h4;
parameter BEGIN_WRITE3 = 4'h5;
parameter BEGIN_WRITE4 = 4'h6;
parameter WRITE = 4'h7;
parameter BEGIN_READ1 = 4'h8;
parameter BEGIN_READ2 = 4'h9;
parameter BEGIN_READ3 = 4'hA;
parameter BEGIN_READ4 = 4'hB;
parameter READ = 4'hC;
parameter END_READ = 4'hD;
parameter INC_PASSES1 = 4'hE;
parameter INC_PASSES2 = 4'hF;
// FSM dispatcher
always @*
begin
case( curr_state )
RESET:
next_state <= INIT1;
INIT1:
if( sram_stop )
next_state <= INIT2;
else
next_state <= INIT1;
INIT2:
next_state <= BEGIN_WRITE1;
BEGIN_WRITE1:
next_state <= BEGIN_WRITE2;
BEGIN_WRITE2:
next_state <= BEGIN_WRITE3;
BEGIN_WRITE3:
next_state <= BEGIN_WRITE4;
BEGIN_WRITE4:
next_state <= WRITE;
WRITE:
if( sram_stop )
next_state <= BEGIN_READ1;
else
next_state <= WRITE;
BEGIN_READ1:
next_state <= BEGIN_READ2;
BEGIN_READ2:
next_state <= BEGIN_READ3;
BEGIN_READ3:
next_state <= BEGIN_READ4;
BEGIN_READ4:
next_state <= READ;
READ:
if( sram_stop )
next_state <= END_READ;
else
next_state <= READ;
END_READ:
next_state <= INC_PASSES1;
INC_PASSES1:
next_state <= INC_PASSES2;
INC_PASSES2:
next_state <= BEGIN_WRITE1;
default:
next_state <= RESET;
endcase
end
// FSM sequencer
always @(posedge clk,negedge rst_n)
begin
if( !rst_n )
curr_state <= RESET;
else
curr_state <= next_state;
end
// FSM controller
always @(posedge clk)
begin
case( curr_state )
//////////////////////////////////////////////////
RESET:
begin
// various initializings begin
inc_pass_ctr <= 1'b0;
check_in_progress <= 1'b0;
rnd_init <= 1'b1; //begin RND init
rnd_save <= 1'b0;
rnd_restore <= 1'b0;
sram_start <= 1'b1;
sram_rnw <= 1'b1; // start condition for sram controller, in read mode
end
INIT1:
begin
sram_start <= 1'b0; // end sram start
end
INIT2:
begin
rnd_init <= 1'b0; // end rnd init
end
//////////////////////////////////////////////////
BEGIN_WRITE1:
begin
rnd_save <= 1'b1;
sram_rnw <= 1'b0;
end
BEGIN_WRITE2:
begin
rnd_save <= 1'b0;
sram_start <= 1'b1;
end
BEGIN_WRITE3:
begin
sram_start <= 1'b0;
end
/* BEGIN_WRITE4:
begin
rnd_save <= 1'b0;
sram_start <= 1'b1;
end
WRITE:
begin
sram_start <= 1'b0;
end
*/
//////////////////////////////////////////////////
BEGIN_READ1:
begin
rnd_restore <= 1'b1;
sram_rnw <= 1'b1;
end
BEGIN_READ2:
begin
rnd_restore <= 1'b0;
sram_start <= 1'b1;
end
BEGIN_READ3:
begin
sram_start <= 1'b0;
check_in_progress <= 1'b1;
end
/* BEGIN_READ4:
begin
rnd_restore <= 1'b0;
sram_start <= 1'b1;
end
READ:
begin
sram_start <= 1'b0;
check_in_progress <= 1'b1;
end
*/
END_READ:
begin
check_in_progress <= 1'b0;
end
INC_PASSES1:
begin
inc_pass_ctr <= 1'b1;
end
INC_PASSES2:
begin
inc_pass_ctr <= 1'b0;
end
endcase
end
// errors counter
always @(posedge clk)
inc_err_ctr <= check_in_progress & sram_ready & ((sram_rdat==rnd_out)?0:1);
endmodule