gateware

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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:
Mhdl/colorlight-sdram.sv | 8+++++---
Mhdl/sdram/testbench.sv | 423+++++++++++++++++++++++--------------------------------------------------------
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)