memtest1.sv (4842B)
1 // Copyright 2020, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0. 3 4 `default_nettype none 5 6 module testbench #( 7 parameter BANKBITS = 1, 8 parameter ROWBITS = 11, 9 parameter COLBITS = 8, 10 parameter DWIDTH = 16 11 ) ( 12 input clk, 13 output reg error = 0, 14 output reg done = 0, 15 16 output reg [XWIDTH-1:0]rd_addr = 0, 17 output reg [3:0]rd_len = 0, 18 output reg rd_req = 0, 19 input wire rd_ack, 20 input wire [DWIDTH-1:0]rd_data, 21 input wire rd_rdy, 22 23 output reg [XWIDTH-1:0]wr_addr = 0, 24 output reg [DWIDTH-1:0]wr_data = 0, 25 output reg [3:0]wr_len = 0, 26 output reg wr_req = 0, 27 input wire wr_ack, 28 29 output reg [15:0]info = 0, 30 output reg info_e = 0 31 ); 32 33 localparam AWIDTH = (ROWBITS + BANKBITS); 34 localparam XWIDTH = (ROWBITS + BANKBITS + COLBITS); 35 36 localparam AMSB = XWIDTH-1; 37 localparam DMSB = DWIDTH-1; 38 39 reg [15:0]info_next; 40 reg info_e_next; 41 42 reg [AMSB:0]rd_addr_next; 43 reg [3:0]rd_len_next; 44 reg rd_req_next; 45 46 reg [AMSB:0]wr_addr_next; 47 reg [DMSB:0]wr_data_next; 48 reg [3:0]wr_len_next; 49 reg wr_req_next; 50 51 reg [31:0]pattern0; 52 reg pattern0_reset = 0; 53 reg pattern0_reset_next; 54 reg pattern0_step = 0; 55 reg pattern0_step_next; 56 57 reg [31:0]pattern1; 58 reg pattern1_reset = 0; 59 reg pattern1_reset_next; 60 reg pattern1_step = 0; 61 reg pattern1_step_next; 62 63 reg [16:0]count = 17'd30000; 64 reg [16:0]count_next; 65 wire count_done = count[16]; 66 wire [16:0]count_minus_one = count - 17'd1; 67 68 localparam START = 3'd0; 69 localparam START2 = 3'd1; 70 localparam WRITE = 3'd2; 71 localparam READ = 3'd3; 72 localparam HALT = 3'd4; 73 74 reg [2:0]state = START; 75 reg [2:0]state_next; 76 77 localparam BLOCK = 17'd1023; 78 79 `define READX16 80 81 reg [DMSB:0]chk_ptn = 0; 82 reg [DMSB:0]chk_ptn_next; 83 reg [DMSB:0]chk_dat = 0; 84 reg [DMSB:0]chk_dat_next; 85 reg chk = 0; 86 reg chk_next; 87 88 reg error_next; 89 90 reg [20:0]colormap = 21'b111110101100011010001; 91 reg [20:0]colormap_next; 92 93 always_comb begin 94 state_next = state; 95 error_next = error; 96 count_next = count; 97 rd_addr_next = rd_addr; 98 rd_req_next = rd_req; 99 rd_len_next = rd_len; 100 wr_addr_next = wr_addr; 101 wr_data_next = wr_data; 102 wr_req_next = wr_req; 103 wr_len_next = wr_len; 104 pattern0_reset_next = 0; 105 pattern1_reset_next = 0; 106 pattern0_step_next = 0; 107 pattern1_step_next = 0; 108 colormap_next = colormap; 109 info_next = info; 110 info_e_next = 0; 111 112 chk_ptn_next = chk_ptn; 113 chk_dat_next = chk_dat; 114 chk_next = 0; 115 116 // verify pipeline 1: capture read data and pattern 117 if (rd_rdy) begin 118 chk_ptn_next = pattern1[DMSB:0]; 119 chk_dat_next = rd_data; 120 chk_next = 1; 121 pattern1_step_next = 1; 122 end 123 124 // verify pipeline 2: compare and flag errors 125 if (chk) begin 126 error_next = (chk_ptn != chk_dat); 127 end 128 129 case (state) 130 START: if (count_done) begin 131 state_next = START2; 132 info_e_next = 1; 133 info_next = { 1'b0, colormap[2:0], 4'h0, 6'h0, rd_addr[19:18] }; 134 end else begin 135 count_next = count_minus_one; 136 end 137 START2: begin 138 info_e_next = 1; 139 info_next = { 1'b0, colormap[2:0], 4'h0, rd_addr[17:10] }; 140 state_next = WRITE; 141 count_next = BLOCK; 142 colormap_next = { colormap[2:0], colormap[20:3] }; 143 end 144 WRITE: if (count_done) begin 145 state_next = READ; 146 `ifdef READX16 147 count_next = 63; 148 `else 149 count_next = BLOCK; 150 `endif 151 end else begin 152 if (wr_req) begin 153 if (wr_ack) begin 154 wr_req_next = 0; 155 wr_addr_next = wr_addr + 1; 156 pattern0_step_next = 1; 157 count_next = count_minus_one; 158 end 159 end else begin 160 wr_req_next = 1; 161 wr_data_next = pattern0[DMSB:0]; 162 end 163 end 164 READ: if (count_done) begin 165 //info_e_next = 1; 166 //info_next = 16'h72CC; 167 state_next = START; 168 count_next = BLOCK; 169 end else begin 170 if (rd_req) begin 171 if (rd_ack) begin 172 rd_req_next = 0; 173 `ifdef READX16 174 rd_addr_next = rd_addr + 16; 175 `else 176 rd_addr_next = rd_addr + 1; 177 `endif 178 count_next = count_minus_one; 179 end 180 end else begin 181 rd_req_next = 1; 182 `ifdef READX16 183 rd_len_next = 15; 184 `endif 185 end 186 end 187 HALT: state_next = HALT; 188 default: state_next = HALT; 189 endcase 190 191 if (error) begin 192 state_next = HALT; 193 info_next = { 16'h40EE }; 194 info_e_next = 1; 195 error_next = 0; 196 rd_req_next = 0; 197 wr_req_next = 0; 198 end 199 end 200 201 reg reset = 1; 202 203 always_ff @(posedge clk) begin 204 reset <= 0; 205 state <= state_next; 206 count <= count_next; 207 rd_addr <= rd_addr_next; 208 rd_req <= rd_req_next; 209 rd_len <= rd_len_next; 210 wr_addr <= wr_addr_next; 211 wr_data <= wr_data_next; 212 wr_req <= wr_req_next; 213 wr_len <= wr_len_next; 214 pattern0_reset <= pattern0_reset_next; 215 pattern1_reset <= pattern1_reset_next; 216 pattern0_step <= pattern0_step_next; 217 pattern1_step <= pattern1_step_next; 218 info <= info_next; 219 info_e <= info_e_next; 220 chk <= chk_next; 221 chk_dat <= chk_dat_next; 222 chk_ptn <= chk_ptn_next; 223 error <= error_next; 224 colormap <= colormap_next; 225 end 226 227 xorshift32 xs0( 228 .clk(clk), 229 .next(pattern0_step_next), 230 .reset(pattern0_reset), 231 .data(pattern0) 232 ); 233 xorshift32 xs1( 234 .clk(clk), 235 .next(pattern1_step_next), 236 .reset(pattern1_reset), 237 .data(pattern1) 238 ); 239 240 endmodule