commit 18a6ba36ae4b9aa6938e29a98e4b94398b88f516
parent 8dbf2e4226d6b897836db6055734ee4d8f0956e2
Author: Brian Swetland <swetland@frotz.net>
Date: Tue, 4 Feb 2020 12:28:05 -0800
sdram: simpler testbench / stress test
Diffstat:
2 files changed, 126 insertions(+), 305 deletions(-)
diff --git a/hdl/colorlight-sdram.sv b/hdl/colorlight-sdram.sv
@@ -80,10 +80,12 @@ assign j1r1 = j1r0;
assign j1b1 = j1b0;
assign j1g1 = j1g0;
-reg [11:0]waddr = 12'd0;
+reg [10:0]waddr = 11'd0;
+
+wire [10:0]waddr_next = (waddr == 11'd1199) ? 11'd0 : (waddr + 11'd1);
always_ff @(posedge testclk) begin
- waddr <= (info_e) ? (waddr + 12'd2) : waddr;
+ waddr <= (info_e) ? waddr_next : waddr;
end
display #(
@@ -101,7 +103,7 @@ display #(
.active(),
.frame(),
.wclk(testclk),
- .waddr(waddr),
+ .waddr({waddr,1'b0}),
.wdata(info),
.we(info_e)
);
diff --git a/hdl/sdram/testbench.sv b/hdl/sdram/testbench.sv
@@ -26,6 +26,7 @@ module testbench #(
output reg info_e = 0
);
+
reg [15:0]info_next;
reg info_e_next;
@@ -44,30 +45,27 @@ reg wr_req_next;
reg [3:0]rd_len_next;
reg [3:0]wr_len_next;
-reg [31:0]addr = 0;
-reg [31:0]data = 0;
-reg [31:0]addr_next;
-reg [31:0]data_next;
+localparam AMSB = 19;
+localparam DMSB = 15;
-reg [31:0]capture = 0;
-reg [31:0]capture_next;
-reg match = 0;
-reg match_next;
+reg [AMSB:0]rd_addr = 0;
+reg [AMSB:0]wr_addr = 0;
+reg [DMSB:0]wr_data = 0;
+reg [AMSB:0]rd_addr_next;
+reg [AMSB:0]wr_addr_next;
+reg [DMSB:0]wr_data_next;
// scratch memory to capture back-to-back and burst read results
-reg [31:0]scratch[0:511];
-reg [8:0]swraddr = 0;
-reg [8:0]srdaddr = 0;
-reg [31:0]srddata = 0;
-reg [8:0]swraddr_next;
-reg [8:0]srdaddr_next;
+reg [DMSB:0]scratch[0:1023];
+reg [9:0]swraddr = 0;
+reg [9:0]srdaddr = 0;
+reg [DMSB:0]srddata = 0;
+reg [9:0]swraddr_next;
+reg [9:0]srdaddr_next;
reg sreset = 0;
reg srd = 0;
-reg sreset_next;
-reg srd_next;
-
always_comb begin
swraddr_next = swraddr;
srdaddr_next = srdaddr;
@@ -77,9 +75,9 @@ always_comb begin
srdaddr_next = 0;
end else begin
if (rd_rdy)
- swraddr_next = swraddr + 9'd1;
+ swraddr_next = swraddr + 10'd1;
if (srd)
- srdaddr_next = srdaddr + 9'd1;
+ srdaddr_next = srdaddr + 10'd1;
end
end
@@ -90,328 +88,160 @@ end
always_ff @(posedge clk) begin
if (rd_rdy)
- scratch[swraddr] <= { 16'h0, rd_data };
- if (srd_next)
+ scratch[swraddr] <= rd_data;
+ if (srd)
srddata <= scratch[srdaddr];
end
-
-wire [15:0]xdata;
-
-`ifdef WITH_SCOPE
-reg [31:0]scope[0:511];
-reg [31:0]scdata = 0;
-reg [8:0]scwp = 0;
-reg [8:0]scrp = 0;
-reg scgo = 0;
-reg scgo_next;
-reg scrd;
-
-wire [31:0]probe = {
- 1'b0, sdram_ras_n, sdram_cas_n, sdram_we_n, sdram_addr, xdata
-};
-
-always @(posedge clk) begin
- scwp <= (scgo && (scwp != 511)) ? scwp + 9'd1 : scwp;
- scrp <= scrd ? scrp + 9'd1 : scrp;
-
- if (scgo)
- scope[scwp] <= probe;
- if (scrd)
- scdata <= scope[scrp];
-end
-`endif
-
-localparam OP_MISC = 4'h0; // all 0 is NOP, see MISC_ bits
-localparam OP_WR_IMM = 4'h1; // value to write
-localparam OP_WR_PAT = 4'h2; // count to write pattern0
-localparam OP_RD_CHK = 4'h3; // value to check against
-localparam OP_RD_PAT = 4'h4; // count to read and check vs pattern1
-localparam OP_VERIFY = 4'h5; // count read data to verify vs pattern
-localparam OP_RD_FAST = 4'h6; // count fast read
-localparam OP_RD_BURST= 4'h7; // count burst read
-localparam OP_ADDR = 4'hA;
-localparam OP_DISPLAY = 4'hD; // write arg to vram
-localparam OP_WAIT = 4'hF;
-
-localparam MISC_RESET_PAT0 = 0;
-localparam MISC_RESET_PAT1 = 1;
-localparam MISC_SET_AUTO = 2;
-localparam MISC_CLR_AUTO = 3;
-localparam MISC_TRIGGER = 29;
-localparam MISC_DUMP = 30;
-localparam MISC_HALT = 31;
-
-localparam START = 4'd0;
-localparam EXEC = 4'd1;
-localparam WRITE = 4'd2;
-localparam READ = 4'd3;
-localparam READ2 = 4'd4;
-localparam SHOW = 4'd5;
-localparam SHOW2 = 4'd6;
-localparam WAIT = 4'd7;
-localparam HALT = 4'd8;
-localparam READFAST = 4'd9;
-localparam READBURST = 4'd12;
-localparam VERIFY = 4'd10;
-localparam VERIFY2 = 4'd11;
-`ifdef WITH_SCOPE
-localparam DUMP0 = 4'd12;
-localparam DUMP1 = 4'd13;
-localparam DUMP2 = 4'd14;
-localparam DUMP3 = 4'd15;
-`endif
-
-reg auto_inc = 0;
-reg auto_inc_next;
-
-wire [31:0]pattern0;
+reg [31:0]pattern0;
reg pattern0_reset = 0;
reg pattern0_reset_next;
reg pattern0_step = 0;
reg pattern0_step_next;
-wire [31:0]pattern1;
+reg [31:0]pattern1;
reg pattern1_reset = 0;
reg pattern1_reset_next;
reg pattern1_step = 0;
reg pattern1_step_next;
-wire p1_match_srddata = (pattern1[15:0] == srddata[15:0]);
-
-reg done_next;
-reg error_next;
-reg [35:0]insram[0:1023];
-reg [35:0]ip = 0;
-reg [9:0]pc = 0;
+reg [16:0]count = 17'd30000;
+reg [16:0]count_next;
+wire count_done = count[16];
+wire [16:0]count_minus_one = count - 17'd1;
-initial $readmemh("hdl/sdram/test.hex", insram);
+localparam START = 4'd0;
+localparam WRITE = 4'd1;
+localparam READ = 4'd2;
+localparam HALT = 4'd3;
+localparam VERIFY = 4'd4;
+localparam DUMP = 4'd5;
+localparam DUMP1 = 4'd6;
+localparam DUMP2 = 4'd7;
+localparam DUMP3 = 4'd8;
reg [3:0]state = START;
reg [3:0]state_next;
-localparam COUNTMSB = 15;
-localparam COUNTONE = 16'd1;
-localparam COUNTZERO = 16'd0;
-reg [COUNTMSB:0]count = 0;
-reg [COUNTMSB:0]count_next;
-wire count_is_zero = (count == COUNTZERO);
-wire [COUNTMSB:0]count_minus_one = (count - COUNTONE);
+localparam BLOCK = 17'd1023;
+
+`define READX16
always_comb begin
state_next = state;
- addr_next = addr;
- data_next = data;
+ count_next = count;
+ rd_addr_next = rd_addr;
rd_req_next = rd_req;
- wr_req_next = wr_req;
rd_len_next = rd_len;
+ wr_addr_next = wr_addr;
+ wr_data_next = wr_data;
+ wr_req_next = wr_req;
wr_len_next = wr_len;
- count_next = count;
pattern0_reset_next = 0;
pattern1_reset_next = 0;
pattern0_step_next = 0;
pattern1_step_next = 0;
- auto_inc_next = auto_inc;
info_next = info;
info_e_next = 0;
- match_next = match;
- capture_next = capture;
- srd_next = 0;
- sreset_next = 0;
-`ifdef WITH_SCOPE
- scgo_next = scgo;
- scrd = 0;
-`endif
+ srd = 0;
+ sreset = 0;
case (state)
- START: begin
- state_next = EXEC;
+ START: if (count_done) begin
+ //info_e_next = 1;
+ //info_next = 16'h72AA;
+ state_next = WRITE;
+ count_next = BLOCK;
+ end else begin
+ count_next = count_minus_one;
end
- EXEC: begin
- case (ip[35:32])
- OP_MISC: begin
- if (ip[MISC_RESET_PAT0]) pattern0_reset_next = 1;
- if (ip[MISC_RESET_PAT1]) pattern1_reset_next = 1;
- if (ip[MISC_SET_AUTO]) auto_inc_next = 1;
- if (ip[MISC_CLR_AUTO]) auto_inc_next = 1;
- if (ip[MISC_HALT]) state_next = HALT;
-`ifdef WITH_SCOPE
- if (ip[MISC_TRIGGER]) scgo_next = 1;
- if (ip[MISC_DUMP]) begin
- state_next = DUMP0;
- count_next = ip[COUNTMSB:0];
- scrd = 1;
- end
-`endif
- end
- OP_WAIT: begin
- state_next = WAIT;
-`ifdef verilator
- count_next = 30;
+ WRITE: if (count_done) begin
+ //info_e_next = 1;
+ //info_next = 16'h72BB;
+ state_next = READ;
+`ifdef READX16
+ count_next = 63;
`else
- count_next = ip[COUNTMSB:0];
+ count_next = BLOCK;
`endif
- end
- OP_ADDR: begin
- addr_next = ip[31:0];
- end
- OP_WR_IMM: begin
- state_next = WRITE;
- data_next = ip[31:0];
- wr_req_next = 1;
- end
- OP_WR_PAT: begin
- state_next = WRITE;
- data_next = pattern0;
- count_next = ip[COUNTMSB:0];
- pattern0_step_next = 1;
- wr_req_next = 1;
- end
- OP_RD_CHK: begin
- state_next = READ;
- data_next = ip[31:0];
- rd_req_next = 1;
- end
- OP_RD_PAT: begin
- state_next = READ;
- data_next = pattern1;
- pattern1_step_next = 1;
- rd_req_next = 1;
- count_next = ip[COUNTMSB:0];
- end
- OP_RD_FAST: begin
- state_next = READFAST;
- rd_req_next = 1;
- sreset_next = 1;
- count_next = ip[COUNTMSB:0];
- end
- OP_RD_BURST: begin
- state_next = READBURST;
- rd_req_next = 1;
- rd_len_next = ip[3:0];
- sreset_next = 1;
- end
- OP_DISPLAY: begin
- info_next = ip[15:0];
- info_e_next = 1;
- end
- OP_VERIFY: begin
- state_next = VERIFY;
- count_next = ip[COUNTMSB:0];
- srd_next = 1;
- end
- default: ;
- endcase
- end
- WRITE: if (wr_ack) begin
- if (count_is_zero) begin
- state_next = EXEC;
- wr_req_next = 0;
- end else begin
- count_next = count_minus_one;
- data_next = pattern0;
- pattern0_step_next = 1;
- end
- if (auto_inc) addr_next = addr + 32'd1;
- end
- READ: if (rd_ack) begin
- state_next = READ2;
- rd_req_next = 0;
- if (auto_inc) addr_next = addr + 32'd1;
- end
- READ2: if (rd_rdy) begin
- state_next = SHOW;
- match_next = (data[15:0] == rd_data);
- capture_next = { 16'h0, rd_data };
- end
- READFAST: if (rd_ack) begin
- if (auto_inc) addr_next = addr + 32'd1;
- if (count_is_zero) begin
- state_next = EXEC;
- rd_req_next = 0;
+ sreset = 1;
+ end else begin
+ if (wr_req) begin
+ if (wr_ack) begin
+ wr_req_next = 0;
+ wr_addr_next = wr_addr + 1;
+ pattern0_step_next = 1;
+ count_next = count_minus_one;
+ end
end else begin
- count_next = count_minus_one;
+ wr_req_next = 1;
+ wr_data_next = pattern0[DMSB:0];
end
end
- READBURST: if (rd_ack) begin
- state_next = EXEC;
- rd_req_next = 0;
- rd_len_next = 0;
- end
- SHOW: begin
- state_next = SHOW2;
- info_next = { match ? 8'h20 : 8'h40, capture[15:8] };
- info_e_next = 1;
- end
- SHOW2: begin
- if (count_is_zero) begin
- state_next = EXEC;
+ READ: if (count_done) begin
+ //info_e_next = 1;
+ //info_next = 16'h72CC;
+ state_next = VERIFY;
+ count_next = BLOCK;
+ srd = 1;
+ end else begin
+ if (rd_req) begin
+ if (rd_ack) begin
+ rd_req_next = 0;
+`ifdef READX16
+ rd_addr_next = rd_addr + 16;
+`else
+ rd_addr_next = rd_addr + 1;
+`endif
+ count_next = count_minus_one;
+ end
end else begin
- state_next = READ;
rd_req_next = 1;
- data_next = pattern1;
- pattern1_step_next = 1;
- count_next = count_minus_one;
+`ifdef READX16
+ rd_len_next = 15;
+`endif
end
- info_next = { match ? 8'h20 : 8'h40, capture[7:0] };
- info_e_next = 1;
end
- VERIFY: begin
- state_next = VERIFY2;
- info_next = { (srddata[15:0] == pattern1[15:0]) ? 8'h20 : 8'h40, srddata[15:8] };
+ VERIFY: if (count_done) begin
info_e_next = 1;
- end
- VERIFY2: begin
- if (count_is_zero) begin
- state_next = EXEC;
- end else begin
- state_next = VERIFY;
+ info_next = { 8'h71 , rd_addr[17:10] };
+ state_next = START;
+ end else begin
+ if (pattern1[DMSB:0] == srddata) begin
+ //info_e_next = 1;
+ //info_next = 16'h7011;
count_next = count_minus_one;
+ srd = 1;
pattern1_step_next = 1;
- srd_next = 1;
+ end else begin
+ info_e_next = 1;
+ info_next = 16'h74EE;
+ state_next = DUMP;
end
- info_next = { (srddata[15:0] == pattern1[15:0]) ? 8'h20 : 8'h40, srddata[7:0] };
- info_e_next = 1;
end
-`ifdef WITH_SCOPE
- DUMP0: begin
- info_next = { 8'h07, scdata[31:24] };
- info_e_next = 1;
+ DUMP: begin
+`ifdef DODUMP
state_next = DUMP1;
+ info_e_next = 1;
+ info_next = { 8'h20, pattern1[15:8] };
end
DUMP1: begin
- info_next = { 8'h70, scdata[23:16] };
- info_e_next = 1;
state_next = DUMP2;
+ info_e_next = 1;
+ info_next = { 8'h20, pattern1[7:0] };
end
DUMP2: begin
- info_next = { 8'h30, scdata[15:8] };
- info_e_next = 1;
state_next = DUMP3;
+ info_e_next = 1;
+ info_next = { 8'h40, srddata[15:8] };
end
DUMP3: begin
- info_next = { 8'h30, scdata[7:0] };
info_e_next = 1;
- if (count_is_zero) begin
- state_next = EXEC;
- end else begin
- state_next = DUMP0;
- count_next = count_minus_one;
- scrd = 1;
- end
- end
+ info_next = { 8'h40, srddata[7:0] };
`endif
- WAIT: if (count_is_zero) begin
- state_next = EXEC;
- end else begin
- count_next = count_minus_one;
- end
- HALT: begin
state_next = HALT;
-`ifdef verilator
- $finish();
-`endif
end
+ HALT: state_next = HALT;
default: state_next = HALT;
endcase
end
@@ -422,30 +252,19 @@ always_ff @(posedge clk) begin
reset <= 0;
state <= state_next;
count <= count_next;
- if (state_next == EXEC) begin
- ip <= insram[pc];
- pc <= pc + 10'd1;
- end
- addr <= addr_next;
- data <= data_next;
+ rd_addr <= rd_addr_next;
+ rd_req <= rd_req_next;
+ rd_len <= rd_len_next;
+ wr_addr <= wr_addr_next;
+ wr_data <= wr_data_next;
+ wr_req <= wr_req_next;
+ wr_len <= wr_len_next;
pattern0_reset <= pattern0_reset_next;
pattern1_reset <= pattern1_reset_next;
pattern0_step <= pattern0_step_next;
pattern1_step <= pattern1_step_next;
- auto_inc <= auto_inc_next;
info <= info_next;
info_e <= info_e_next;
- match <= match_next;
- capture <= capture_next;
- wr_req <= wr_req_next;
- rd_req <= rd_req_next;
- wr_len <= wr_len_next;
- rd_len <= rd_len_next;
- srd <= srd_next;
- sreset <= sreset_next;
-`ifdef WITH_SCOPE
- scgo <= scgo_next;
-`endif
end
xorshift32 xs0(
@@ -479,15 +298,15 @@ sdram #(
`else
.pin_data(sdram_data),
`endif
- .rd_addr(addr[19:0]),
+ .rd_addr(rd_addr),
.rd_len(rd_len),
.rd_req(rd_req),
.rd_ack(rd_ack),
.rd_data(rd_data),
.rd_rdy(rd_rdy),
- .wr_addr(addr[19:0]),
- .wr_data(data[15:0]),
+ .wr_addr(wr_addr),
+ .wr_data(wr_data),
.wr_len(wr_len),
.wr_req(wr_req),
.wr_ack(wr_ack)