blob: dc37126a45e972dc96c5a1bf02971bea979ca8b1 [file] [log] [blame]
Matt Venn08cd6eb2020-11-16 12:01:14 +01001`default_nettype none
Tim Edwardscd64af52020-08-07 11:11:58 -04002/*
3 * PicoSoC - A simple example SoC using PicoRV32
4 *
5 * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
shalanfd13eb52020-08-21 16:48:07 +020021module spimemio_wb (
22 input wb_clk_i,
23 input wb_rst_i,
Tim Edwardscd64af52020-08-07 11:11:58 -040024
shalanfd13eb52020-08-21 16:48:07 +020025 input [31:0] wb_adr_i,
Tim Edwards04ba17f2020-10-02 22:27:50 -040026 input [31:0] wb_dat_i,
shalanfd13eb52020-08-21 16:48:07 +020027 input [3:0] wb_sel_i,
28 input wb_we_i,
29 input wb_cyc_i,
Tim Edwardscd64af52020-08-07 11:11:58 -040030
shalanfd13eb52020-08-21 16:48:07 +020031 input wb_flash_stb_i,
32 input wb_cfg_stb_i,
Tim Edwardscd64af52020-08-07 11:11:58 -040033
shalanfd13eb52020-08-21 16:48:07 +020034 output wb_flash_ack_o,
35 output wb_cfg_ack_o,
Tim Edwardscd64af52020-08-07 11:11:58 -040036
shalanfd13eb52020-08-21 16:48:07 +020037 output [31:0] wb_flash_dat_o,
38 output [31:0] wb_cfg_dat_o,
Tim Edwardscd64af52020-08-07 11:11:58 -040039
Tim Edwards04ba17f2020-10-02 22:27:50 -040040 input pass_thru,
41 input pass_thru_csb,
42 input pass_thru_sck,
43 input pass_thru_sdi,
44 output pass_thru_sdo,
45
shalanfd13eb52020-08-21 16:48:07 +020046 output flash_csb,
47 output flash_clk,
Tim Edwardscd64af52020-08-07 11:11:58 -040048
shalanfd13eb52020-08-21 16:48:07 +020049 output flash_csb_oeb,
50 output flash_clk_oeb,
Tim Edwardscd64af52020-08-07 11:11:58 -040051
shalanfd13eb52020-08-21 16:48:07 +020052 output flash_io0_oeb,
53 output flash_io1_oeb,
54 output flash_io2_oeb,
55 output flash_io3_oeb,
Tim Edwardscd64af52020-08-07 11:11:58 -040056
shalanfd13eb52020-08-21 16:48:07 +020057 output flash_csb_ieb,
58 output flash_clk_ieb,
Tim Edwardscd64af52020-08-07 11:11:58 -040059
shalanfd13eb52020-08-21 16:48:07 +020060 output flash_io0_ieb,
61 output flash_io1_ieb,
62 output flash_io2_ieb,
63 output flash_io3_ieb,
64
65 output flash_io0_do,
66 output flash_io1_do,
67 output flash_io2_do,
68 output flash_io3_do,
69
70 input flash_io0_di,
71 input flash_io1_di,
72 input flash_io2_di,
73 input flash_io3_di
74
Tim Edwardscd64af52020-08-07 11:11:58 -040075);
shalanfd13eb52020-08-21 16:48:07 +020076 wire spimem_ready;
77 wire [23:0] mem_addr;
78 wire [31:0] spimem_rdata;
79 wire [31:0] spimemio_cfgreg_do;
80 wire [3:0] cfgreg_we;
81 wire spimemio_cfgreg_sel;
82 wire valid;
83 wire resetn;
Tim Edwardscd64af52020-08-07 11:11:58 -040084
shalanfd13eb52020-08-21 16:48:07 +020085 assign resetn = ~wb_rst_i;
86 assign valid = wb_cyc_i && wb_flash_stb_i;
87 assign wb_flash_ack_o = spimem_ready;
88 assign wb_cfg_ack_o = spimemio_cfgreg_sel;
Tim Edwardscd64af52020-08-07 11:11:58 -040089
shalanfd13eb52020-08-21 16:48:07 +020090 assign mem_addr = wb_adr_i[23:0];
91 assign spimemio_cfgreg_sel = wb_cyc_i && wb_cfg_stb_i;
Tim Edwardscd64af52020-08-07 11:11:58 -040092
shalanfd13eb52020-08-21 16:48:07 +020093 assign cfgreg_we = spimemio_cfgreg_sel ? wb_sel_i & {4{wb_we_i}} : 4'b 0000;
94 assign wb_flash_dat_o = spimem_rdata;
95 assign wb_cfg_dat_o = spimemio_cfgreg_do;
Tim Edwardscd64af52020-08-07 11:11:58 -040096
shalanfd13eb52020-08-21 16:48:07 +020097 spimemio spimemio (
98 .clk (wb_clk_i),
99 .resetn (resetn),
100 .valid (valid),
101 .ready (spimem_ready),
102 .addr (mem_addr),
103 .rdata (spimem_rdata),
Tim Edwardscd64af52020-08-07 11:11:58 -0400104
shalanfd13eb52020-08-21 16:48:07 +0200105 .flash_csb (flash_csb),
106 .flash_clk (flash_clk),
Tim Edwardscd64af52020-08-07 11:11:58 -0400107
shalanfd13eb52020-08-21 16:48:07 +0200108 .flash_csb_oeb (flash_csb_oeb),
109 .flash_clk_oeb (flash_clk_oeb),
Tim Edwardscd64af52020-08-07 11:11:58 -0400110
shalanfd13eb52020-08-21 16:48:07 +0200111 .flash_io0_oeb (flash_io0_oeb),
112 .flash_io1_oeb (flash_io1_oeb),
113 .flash_io2_oeb (flash_io2_oeb),
114 .flash_io3_oeb (flash_io3_oeb),
Tim Edwardscd64af52020-08-07 11:11:58 -0400115
shalanfd13eb52020-08-21 16:48:07 +0200116 .flash_csb_ieb (flash_csb_ieb),
117 .flash_clk_ieb (flash_clk_ieb),
Tim Edwardscd64af52020-08-07 11:11:58 -0400118
shalanfd13eb52020-08-21 16:48:07 +0200119 .flash_io0_ieb (flash_io0_ieb),
120 .flash_io1_ieb (flash_io1_ieb),
121 .flash_io2_ieb (flash_io2_ieb),
122 .flash_io3_ieb (flash_io3_ieb),
Tim Edwardscd64af52020-08-07 11:11:58 -0400123
shalanfd13eb52020-08-21 16:48:07 +0200124 .flash_io0_do (flash_io0_do),
125 .flash_io1_do (flash_io1_do),
126 .flash_io2_do (flash_io2_do),
127 .flash_io3_do (flash_io3_do),
Tim Edwardscd64af52020-08-07 11:11:58 -0400128
shalanfd13eb52020-08-21 16:48:07 +0200129 .flash_io0_di (flash_io0_di),
130 .flash_io1_di (flash_io1_di),
131 .flash_io2_di (flash_io2_di),
132 .flash_io3_di (flash_io3_di),
Tim Edwardscd64af52020-08-07 11:11:58 -0400133
shalanfd13eb52020-08-21 16:48:07 +0200134 .cfgreg_we(cfgreg_we),
135 .cfgreg_di(wb_dat_i),
Tim Edwards44bab472020-10-04 22:09:54 -0400136 .cfgreg_do(spimemio_cfgreg_do),
137
138 .pass_thru(pass_thru),
139 .pass_thru_csb(pass_thru_csb),
140 .pass_thru_sck(pass_thru_sck),
141 .pass_thru_sdi(pass_thru_sdi),
142 .pass_thru_sdo(pass_thru_sdo)
shalanfd13eb52020-08-21 16:48:07 +0200143 );
Tim Edwardscd64af52020-08-07 11:11:58 -0400144
shalanfd13eb52020-08-21 16:48:07 +0200145endmodule
Tim Edwardscd64af52020-08-07 11:11:58 -0400146
shalanfd13eb52020-08-21 16:48:07 +0200147module spimemio (
148 input clk, resetn,
Tim Edwardscd64af52020-08-07 11:11:58 -0400149
shalanfd13eb52020-08-21 16:48:07 +0200150 input valid,
151 output ready,
152 input [23:0] addr,
153 output reg [31:0] rdata,
Tim Edwardscd64af52020-08-07 11:11:58 -0400154
shalanfd13eb52020-08-21 16:48:07 +0200155 output flash_csb,
156 output flash_clk,
Tim Edwardscd64af52020-08-07 11:11:58 -0400157
shalanfd13eb52020-08-21 16:48:07 +0200158 output flash_csb_oeb,
159 output flash_clk_oeb,
Tim Edwardscd64af52020-08-07 11:11:58 -0400160
shalanfd13eb52020-08-21 16:48:07 +0200161 output flash_io0_oeb,
162 output flash_io1_oeb,
163 output flash_io2_oeb,
164 output flash_io3_oeb,
Tim Edwardscd64af52020-08-07 11:11:58 -0400165
shalanfd13eb52020-08-21 16:48:07 +0200166 output flash_csb_ieb,
167 output flash_clk_ieb,
Tim Edwardscd64af52020-08-07 11:11:58 -0400168
shalanfd13eb52020-08-21 16:48:07 +0200169 output flash_io0_ieb,
170 output flash_io1_ieb,
171 output flash_io2_ieb,
172 output flash_io3_ieb,
Tim Edwardscd64af52020-08-07 11:11:58 -0400173
shalanfd13eb52020-08-21 16:48:07 +0200174 output flash_io0_do,
175 output flash_io1_do,
176 output flash_io2_do,
177 output flash_io3_do,
Tim Edwardscd64af52020-08-07 11:11:58 -0400178
shalanfd13eb52020-08-21 16:48:07 +0200179 input flash_io0_di,
180 input flash_io1_di,
181 input flash_io2_di,
182 input flash_io3_di,
Tim Edwardscd64af52020-08-07 11:11:58 -0400183
shalanfd13eb52020-08-21 16:48:07 +0200184 input [3:0] cfgreg_we,
185 input [31:0] cfgreg_di,
Tim Edwards44bab472020-10-04 22:09:54 -0400186 output [31:0] cfgreg_do,
187
188 input pass_thru,
189 input pass_thru_csb,
190 input pass_thru_sck,
191 input pass_thru_sdi,
192 output pass_thru_sdo
shalanfd13eb52020-08-21 16:48:07 +0200193);
194 reg xfer_resetn;
195 reg din_valid;
196 wire din_ready;
197 reg [7:0] din_data;
198 reg [3:0] din_tag;
199 reg din_cont;
200 reg din_qspi;
201 reg din_ddr;
202 reg din_rd;
Tim Edwardscd64af52020-08-07 11:11:58 -0400203
shalanfd13eb52020-08-21 16:48:07 +0200204 wire dout_valid;
205 wire [7:0] dout_data;
206 wire [3:0] dout_tag;
Tim Edwardscd64af52020-08-07 11:11:58 -0400207
shalanfd13eb52020-08-21 16:48:07 +0200208 reg [23:0] buffer;
Tim Edwardscd64af52020-08-07 11:11:58 -0400209
shalanfd13eb52020-08-21 16:48:07 +0200210 reg [23:0] rd_addr;
211 reg rd_valid;
212 reg rd_wait;
213 reg rd_inc;
214
215 assign ready = valid && (addr == rd_addr) && rd_valid;
216 wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid;
217
218 reg softreset;
219
220 reg config_en; // cfgreg[31]
221 reg config_ddr; // cfgreg[22]
222 reg config_qspi; // cfgreg[21]
223 reg config_cont; // cfgreg[20]
224 reg [3:0] config_dummy; // cfgreg[19:16]
225 reg [3:0] config_oe; // cfgreg[11:8]
226 reg config_csb; // cfgreg[5]
227 reg config_clk; // cfgref[4]
228 reg [3:0] config_do; // cfgreg[3:0]
229
230 assign cfgreg_do[31] = config_en;
231 assign cfgreg_do[30:23] = 0;
232 assign cfgreg_do[22] = config_ddr;
233 assign cfgreg_do[21] = config_qspi;
234 assign cfgreg_do[20] = config_cont;
235 assign cfgreg_do[19:16] = config_dummy;
236 assign cfgreg_do[15:12] = 0;
237 assign cfgreg_do[11:8] = {~flash_io3_oeb, ~flash_io2_oeb, ~flash_io1_oeb, ~flash_io0_oeb};
238 assign cfgreg_do[7:6] = 0;
239 assign cfgreg_do[5] = flash_csb;
240 assign cfgreg_do[4] = flash_clk;
241 assign cfgreg_do[3:0] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
242
243 always @(posedge clk) begin
244 softreset <= !config_en || cfgreg_we;
245 if (!resetn) begin
246 softreset <= 1;
247 config_en <= 1;
248 config_csb <= 0;
249 config_clk <= 0;
250 config_oe <= 0;
251 config_do <= 0;
252 config_ddr <= 0;
253 config_qspi <= 0;
254 config_cont <= 0;
255 config_dummy <= 8;
256 end else begin
257 if (cfgreg_we[0]) begin
258 config_csb <= cfgreg_di[5];
259 config_clk <= cfgreg_di[4];
260 config_do <= cfgreg_di[3:0];
261 end
262 if (cfgreg_we[1]) begin
263 config_oe <= cfgreg_di[11:8];
264 end
265 if (cfgreg_we[2]) begin
266 config_ddr <= cfgreg_di[22];
267 config_qspi <= cfgreg_di[21];
268 config_cont <= cfgreg_di[20];
269 config_dummy <= cfgreg_di[19:16];
270 end
271 if (cfgreg_we[3]) begin
272 config_en <= cfgreg_di[31];
273 end
274 end
275 end
276
277 wire xfer_csb;
278 wire xfer_clk;
279
280 wire xfer_io0_oe;
281 wire xfer_io1_oe;
282 wire xfer_io2_oe;
283 wire xfer_io3_oe;
284
285 wire xfer_io0_do;
286 wire xfer_io1_do;
287 wire xfer_io2_do;
288 wire xfer_io3_do;
289
290 reg xfer_io0_90;
291 reg xfer_io1_90;
292 reg xfer_io2_90;
293 reg xfer_io3_90;
294
295 always @(negedge clk) begin
296 xfer_io0_90 <= xfer_io0_do;
297 xfer_io1_90 <= xfer_io1_do;
298 xfer_io2_90 <= xfer_io2_do;
299 xfer_io3_90 <= xfer_io3_do;
300 end
301
Tim Edwards04ba17f2020-10-02 22:27:50 -0400302 wire pass_thru;
303 wire pass_thru_csb;
304 wire pass_thru_sck;
305 wire pass_thru_sdi;
306 wire pass_thru_sdo;
shalanfd13eb52020-08-21 16:48:07 +0200307
Tim Edwards04ba17f2020-10-02 22:27:50 -0400308 assign flash_csb = (pass_thru) ? pass_thru_csb : (config_en ? xfer_csb : config_csb);
309 assign flash_clk = (pass_thru) ? pass_thru_sck : (config_en ? xfer_clk : config_clk);
shalanfd13eb52020-08-21 16:48:07 +0200310
Tim Edwards04ba17f2020-10-02 22:27:50 -0400311 assign flash_csb_oeb = (pass_thru) ? 1'b0 : (~resetn ? 1'b1 : 1'b0);
312 assign flash_clk_oeb = (pass_thru) ? 1'b0 : (~resetn ? 1'b1 : 1'b0);
313
314 assign flash_io0_oeb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : (config_en ? ~xfer_io0_oe : ~config_oe[0]);
315 assign flash_io1_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io1_oe : ~config_oe[1]);
316 assign flash_io2_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io2_oe : ~config_oe[2]);
317 assign flash_io3_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io3_oe : ~config_oe[3]);
shalanfd13eb52020-08-21 16:48:07 +0200318 assign flash_csb_ieb = 1'b1; /* Always disabled */
319 assign flash_clk_ieb = 1'b1; /* Always disabled */
320
Tim Edwards04ba17f2020-10-02 22:27:50 -0400321 assign flash_io0_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io0_oe : config_oe[0]);
Tim Edwardsb78e1c12020-10-09 11:51:48 -0400322 assign flash_io1_ieb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]);
Tim Edwards04ba17f2020-10-02 22:27:50 -0400323 assign flash_io2_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io2_oe : config_oe[2]);
324 assign flash_io3_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io3_oe : config_oe[3]);
shalanfd13eb52020-08-21 16:48:07 +0200325
Tim Edwards04ba17f2020-10-02 22:27:50 -0400326 assign flash_io0_do = pass_thru ? pass_thru_sdi : (config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0]);
shalanfd13eb52020-08-21 16:48:07 +0200327 assign flash_io1_do = config_en ? (config_ddr ? xfer_io1_90 : xfer_io1_do) : config_do[1];
328 assign flash_io2_do = config_en ? (config_ddr ? xfer_io2_90 : xfer_io2_do) : config_do[2];
329 assign flash_io3_do = config_en ? (config_ddr ? xfer_io3_90 : xfer_io3_do) : config_do[3];
Tim Edwards04ba17f2020-10-02 22:27:50 -0400330 assign pass_thru_sdo = pass_thru ? flash_io1_di : 1'b0;
shalanfd13eb52020-08-21 16:48:07 +0200331
332 wire xfer_dspi = din_ddr && !din_qspi;
333 wire xfer_ddr = din_ddr && din_qspi;
334
335 spimemio_xfer xfer (
336 .clk (clk ),
337 .resetn (resetn ),
338 .xfer_resetn (xfer_resetn ),
339 .din_valid (din_valid ),
340 .din_ready (din_ready ),
341 .din_data (din_data ),
342 .din_tag (din_tag ),
343 .din_cont (din_cont ),
344 .din_dspi (xfer_dspi ),
345 .din_qspi (din_qspi ),
346 .din_ddr (xfer_ddr ),
347 .din_rd (din_rd ),
348 .dout_valid (dout_valid ),
349 .dout_data (dout_data ),
350 .dout_tag (dout_tag ),
351 .flash_csb (xfer_csb ),
352 .flash_clk (xfer_clk ),
353 .flash_io0_oe (xfer_io0_oe ),
354 .flash_io1_oe (xfer_io1_oe ),
355 .flash_io2_oe (xfer_io2_oe ),
356 .flash_io3_oe (xfer_io3_oe ),
357 .flash_io0_do (xfer_io0_do ),
358 .flash_io1_do (xfer_io1_do ),
359 .flash_io2_do (xfer_io2_do ),
360 .flash_io3_do (xfer_io3_do ),
361 .flash_io0_di (flash_io0_di),
362 .flash_io1_di (flash_io1_di),
363 .flash_io2_di (flash_io2_di),
364 .flash_io3_di (flash_io3_di)
365 );
366
367 reg [3:0] state;
368
369 always @(posedge clk) begin
370 xfer_resetn <= 1;
371 din_valid <= 0;
372
373 if (!resetn || softreset) begin
374 state <= 0;
375 xfer_resetn <= 0;
376 rd_valid <= 0;
377 din_tag <= 0;
378 din_cont <= 0;
379 din_qspi <= 0;
380 din_ddr <= 0;
381 din_rd <= 0;
382 end else begin
383 if (dout_valid && dout_tag == 1) buffer[ 7: 0] <= dout_data;
384 if (dout_valid && dout_tag == 2) buffer[15: 8] <= dout_data;
385 if (dout_valid && dout_tag == 3) buffer[23:16] <= dout_data;
386 if (dout_valid && dout_tag == 4) begin
387 rdata <= {dout_data, buffer};
388 rd_addr <= rd_inc ? rd_addr + 4 : addr;
389 rd_valid <= 1;
390 rd_wait <= rd_inc;
391 rd_inc <= 1;
392 end
393
394 if (valid)
395 rd_wait <= 0;
396
397 case (state)
398 0: begin
399 din_valid <= 1;
400 din_data <= 8'h ff;
401 din_tag <= 0;
402 if (din_ready) begin
403 din_valid <= 0;
404 state <= 1;
405 end
406 end
407 1: begin
408 if (dout_valid) begin
409 xfer_resetn <= 0;
410 state <= 2;
411 end
412 end
413 2: begin
414 din_valid <= 1;
415 din_data <= 8'h ab;
416 din_tag <= 0;
417 if (din_ready) begin
418 din_valid <= 0;
419 state <= 3;
420 end
421 end
422 3: begin
423 if (dout_valid) begin
424 xfer_resetn <= 0;
425 state <= 4;
426 end
427 end
428 4: begin
429 rd_inc <= 0;
430 din_valid <= 1;
431 din_tag <= 0;
432 case ({config_ddr, config_qspi})
433 2'b11: din_data <= 8'h ED;
434 2'b01: din_data <= 8'h EB;
435 2'b10: din_data <= 8'h BB;
436 2'b00: din_data <= 8'h 03;
437 endcase
438 if (din_ready) begin
439 din_valid <= 0;
440 state <= 5;
441 end
442 end
443 5: begin
444 if (valid && !ready) begin
445 din_valid <= 1;
446 din_tag <= 0;
447 din_data <= addr[23:16];
448 din_qspi <= config_qspi;
449 din_ddr <= config_ddr;
450 if (din_ready) begin
451 din_valid <= 0;
452 state <= 6;
453 end
454 end
455 end
456 6: begin
457 din_valid <= 1;
458 din_tag <= 0;
459 din_data <= addr[15:8];
460 if (din_ready) begin
461 din_valid <= 0;
462 state <= 7;
463 end
464 end
465 7: begin
466 din_valid <= 1;
467 din_tag <= 0;
468 din_data <= addr[7:0];
469 if (din_ready) begin
470 din_valid <= 0;
471 din_data <= 0;
472 state <= config_qspi || config_ddr ? 8 : 9;
473 end
474 end
475 8: begin
476 din_valid <= 1;
477 din_tag <= 0;
478 din_data <= config_cont ? 8'h A5 : 8'h FF;
479 if (din_ready) begin
480 din_rd <= 1;
481 din_data <= config_dummy;
482 din_valid <= 0;
483 state <= 9;
484 end
485 end
486 9: begin
487 din_valid <= 1;
488 din_tag <= 1;
489 if (din_ready) begin
490 din_valid <= 0;
491 state <= 10;
492 end
493 end
494 10: begin
495 din_valid <= 1;
496 din_data <= 8'h 00;
497 din_tag <= 2;
498 if (din_ready) begin
499 din_valid <= 0;
500 state <= 11;
501 end
502 end
503 11: begin
504 din_valid <= 1;
505 din_tag <= 3;
506 if (din_ready) begin
507 din_valid <= 0;
508 state <= 12;
509 end
510 end
511 12: begin
512 if (!rd_wait || valid) begin
513 din_valid <= 1;
514 din_tag <= 4;
515 if (din_ready) begin
516 din_valid <= 0;
517 state <= 9;
518 end
519 end
520 end
521 endcase
522
523 if (jump) begin
524 rd_inc <= 0;
525 rd_valid <= 0;
526 xfer_resetn <= 0;
527 if (config_cont) begin
528 state <= 5;
529 end else begin
530 state <= 4;
531 din_qspi <= 0;
532 din_ddr <= 0;
533 end
534 din_rd <= 0;
535 end
536 end
537 end
Tim Edwardscd64af52020-08-07 11:11:58 -0400538endmodule
539
540module spimemio_xfer (
shalanfd13eb52020-08-21 16:48:07 +0200541 input clk, resetn, xfer_resetn,
Tim Edwardscd64af52020-08-07 11:11:58 -0400542
shalanfd13eb52020-08-21 16:48:07 +0200543 input din_valid,
544 output din_ready,
545 input [7:0] din_data,
546 input [3:0] din_tag,
547 input din_cont,
548 input din_dspi,
549 input din_qspi,
550 input din_ddr,
551 input din_rd,
Tim Edwardscd64af52020-08-07 11:11:58 -0400552
shalanfd13eb52020-08-21 16:48:07 +0200553 output dout_valid,
554 output [7:0] dout_data,
555 output [3:0] dout_tag,
Tim Edwardscd64af52020-08-07 11:11:58 -0400556
shalanfd13eb52020-08-21 16:48:07 +0200557 output reg flash_csb,
558 output reg flash_clk,
Tim Edwardscd64af52020-08-07 11:11:58 -0400559
shalanfd13eb52020-08-21 16:48:07 +0200560 output reg flash_io0_oe,
561 output reg flash_io1_oe,
562 output reg flash_io2_oe,
563 output reg flash_io3_oe,
Tim Edwardscd64af52020-08-07 11:11:58 -0400564
shalanfd13eb52020-08-21 16:48:07 +0200565 output reg flash_io0_do,
566 output reg flash_io1_do,
567 output reg flash_io2_do,
568 output reg flash_io3_do,
Tim Edwardscd64af52020-08-07 11:11:58 -0400569
shalanfd13eb52020-08-21 16:48:07 +0200570 input flash_io0_di,
571 input flash_io1_di,
572 input flash_io2_di,
573 input flash_io3_di
Tim Edwardscd64af52020-08-07 11:11:58 -0400574);
shalanfd13eb52020-08-21 16:48:07 +0200575 reg [7:0] obuffer;
576 reg [7:0] ibuffer;
Tim Edwardscd64af52020-08-07 11:11:58 -0400577
shalanfd13eb52020-08-21 16:48:07 +0200578 reg [3:0] count;
579 reg [3:0] dummy_count;
Tim Edwardscd64af52020-08-07 11:11:58 -0400580
shalanfd13eb52020-08-21 16:48:07 +0200581 reg xfer_cont;
582 reg xfer_dspi;
583 reg xfer_qspi;
584 reg xfer_ddr;
585 reg xfer_ddr_q;
586 reg xfer_rd;
587 reg [3:0] xfer_tag;
588 reg [3:0] xfer_tag_q;
Tim Edwardscd64af52020-08-07 11:11:58 -0400589
shalanfd13eb52020-08-21 16:48:07 +0200590 reg [7:0] next_obuffer;
591 reg [7:0] next_ibuffer;
592 reg [3:0] next_count;
Tim Edwardscd64af52020-08-07 11:11:58 -0400593
shalanfd13eb52020-08-21 16:48:07 +0200594 reg fetch;
595 reg next_fetch;
596 reg last_fetch;
Tim Edwardscd64af52020-08-07 11:11:58 -0400597
shalanfd13eb52020-08-21 16:48:07 +0200598 always @(posedge clk) begin
599 xfer_ddr_q <= xfer_ddr;
600 xfer_tag_q <= xfer_tag;
601 end
Tim Edwardscd64af52020-08-07 11:11:58 -0400602
shalanfd13eb52020-08-21 16:48:07 +0200603 assign din_ready = din_valid && xfer_resetn && next_fetch;
Tim Edwardscd64af52020-08-07 11:11:58 -0400604
shalanfd13eb52020-08-21 16:48:07 +0200605 assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && xfer_resetn;
606 assign dout_data = ibuffer;
607 assign dout_tag = xfer_tag_q;
Tim Edwardscd64af52020-08-07 11:11:58 -0400608
shalanfd13eb52020-08-21 16:48:07 +0200609 always @* begin
610 flash_io0_oe = 0;
611 flash_io1_oe = 0;
612 flash_io2_oe = 0;
613 flash_io3_oe = 0;
Tim Edwardscd64af52020-08-07 11:11:58 -0400614
shalanfd13eb52020-08-21 16:48:07 +0200615 flash_io0_do = 0;
616 flash_io1_do = 0;
617 flash_io2_do = 0;
618 flash_io3_do = 0;
Tim Edwardscd64af52020-08-07 11:11:58 -0400619
shalanfd13eb52020-08-21 16:48:07 +0200620 next_obuffer = obuffer;
621 next_ibuffer = ibuffer;
622 next_count = count;
623 next_fetch = 0;
Tim Edwardscd64af52020-08-07 11:11:58 -0400624
shalanfd13eb52020-08-21 16:48:07 +0200625 if (dummy_count == 0) begin
626 casez ({xfer_ddr, xfer_qspi, xfer_dspi})
627 3'b 000: begin
628 flash_io0_oe = 1;
629 flash_io0_do = obuffer[7];
Tim Edwardscd64af52020-08-07 11:11:58 -0400630
shalanfd13eb52020-08-21 16:48:07 +0200631 if (flash_clk) begin
632 next_obuffer = {obuffer[6:0], 1'b 0};
633 next_count = count - |count;
634 end else begin
635 next_ibuffer = {ibuffer[6:0], flash_io1_di};
636 end
Tim Edwardscd64af52020-08-07 11:11:58 -0400637
shalanfd13eb52020-08-21 16:48:07 +0200638 next_fetch = (next_count == 0);
639 end
640 3'b 01?: begin
641 flash_io0_oe = !xfer_rd;
642 flash_io1_oe = !xfer_rd;
643 flash_io2_oe = !xfer_rd;
644 flash_io3_oe = !xfer_rd;
Tim Edwardscd64af52020-08-07 11:11:58 -0400645
shalanfd13eb52020-08-21 16:48:07 +0200646 flash_io0_do = obuffer[4];
647 flash_io1_do = obuffer[5];
648 flash_io2_do = obuffer[6];
649 flash_io3_do = obuffer[7];
Tim Edwardscd64af52020-08-07 11:11:58 -0400650
shalanfd13eb52020-08-21 16:48:07 +0200651 if (flash_clk) begin
652 next_obuffer = {obuffer[3:0], 4'b 0000};
653 next_count = count - {|count, 2'b00};
654 end else begin
655 next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
656 end
Tim Edwardscd64af52020-08-07 11:11:58 -0400657
shalanfd13eb52020-08-21 16:48:07 +0200658 next_fetch = (next_count == 0);
659 end
660 3'b 11?: begin
661 flash_io0_oe = !xfer_rd;
662 flash_io1_oe = !xfer_rd;
663 flash_io2_oe = !xfer_rd;
664 flash_io3_oe = !xfer_rd;
Tim Edwardscd64af52020-08-07 11:11:58 -0400665
shalanfd13eb52020-08-21 16:48:07 +0200666 flash_io0_do = obuffer[4];
667 flash_io1_do = obuffer[5];
668 flash_io2_do = obuffer[6];
669 flash_io3_do = obuffer[7];
Tim Edwardscd64af52020-08-07 11:11:58 -0400670
shalanfd13eb52020-08-21 16:48:07 +0200671 next_obuffer = {obuffer[3:0], 4'b 0000};
672 next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
673 next_count = count - {|count, 2'b00};
Tim Edwardscd64af52020-08-07 11:11:58 -0400674
shalanfd13eb52020-08-21 16:48:07 +0200675 next_fetch = (next_count == 0);
676 end
677 3'b ??1: begin
678 flash_io0_oe = !xfer_rd;
679 flash_io1_oe = !xfer_rd;
Tim Edwardscd64af52020-08-07 11:11:58 -0400680
shalanfd13eb52020-08-21 16:48:07 +0200681 flash_io0_do = obuffer[6];
682 flash_io1_do = obuffer[7];
Tim Edwardscd64af52020-08-07 11:11:58 -0400683
shalanfd13eb52020-08-21 16:48:07 +0200684 if (flash_clk) begin
685 next_obuffer = {obuffer[5:0], 2'b 00};
686 next_count = count - {|count, 1'b0};
687 end else begin
688 next_ibuffer = {ibuffer[5:0], flash_io1_di, flash_io0_di};
689 end
Tim Edwardscd64af52020-08-07 11:11:58 -0400690
shalanfd13eb52020-08-21 16:48:07 +0200691 next_fetch = (next_count == 0);
692 end
693 endcase
694 end
695 end
Tim Edwardscd64af52020-08-07 11:11:58 -0400696
shalanfd13eb52020-08-21 16:48:07 +0200697 always @(posedge clk) begin
698 if (!resetn || !xfer_resetn) begin
699 fetch <= 1;
700 last_fetch <= 1;
701 flash_csb <= 1;
702 flash_clk <= 0;
703 count <= 0;
704 dummy_count <= 0;
705 xfer_tag <= 0;
706 xfer_cont <= 0;
707 xfer_dspi <= 0;
708 xfer_qspi <= 0;
709 xfer_ddr <= 0;
710 xfer_rd <= 0;
711 end else begin
712 fetch <= next_fetch;
713 last_fetch <= xfer_ddr ? fetch : 1;
714 if (dummy_count) begin
715 flash_clk <= !flash_clk && !flash_csb;
716 dummy_count <= dummy_count - flash_clk;
717 end else
718 if (count) begin
719 flash_clk <= !flash_clk && !flash_csb;
720 obuffer <= next_obuffer;
721 ibuffer <= next_ibuffer;
722 count <= next_count;
723 end
724 if (din_valid && din_ready) begin
725 flash_csb <= 0;
726 flash_clk <= 0;
Tim Edwardscd64af52020-08-07 11:11:58 -0400727
shalanfd13eb52020-08-21 16:48:07 +0200728 count <= 8;
729 dummy_count <= din_rd ? din_data : 0;
730 obuffer <= din_data;
Tim Edwardscd64af52020-08-07 11:11:58 -0400731
shalanfd13eb52020-08-21 16:48:07 +0200732 xfer_tag <= din_tag;
733 xfer_cont <= din_cont;
734 xfer_dspi <= din_dspi;
735 xfer_qspi <= din_qspi;
736 xfer_ddr <= din_ddr;
737 xfer_rd <= din_rd;
738 end
739 end
740 end
Tim Edwardscd64af52020-08-07 11:11:58 -0400741endmodule
shalanfd13eb52020-08-21 16:48:07 +0200742
Tim Edwards581068f2020-11-19 12:45:25 -0500743`default_nettype wire