OpenCores
URL https://opencores.org/ocsvn/qspiflash/qspiflash/trunk

Subversion Repositories qspiflash

[/] [qspiflash/] [trunk/] [rtl/] [wbqspiflash.v] - Blame information for rev 9

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 dgisselq
///////////////////////////////////////////////////////////////////////////
2 2 dgisselq
//
3
// Filename:    wbspiflash.v
4
//
5 3 dgisselq
// Project:     Wishbone Controlled Quad SPI Flash Controller
6 2 dgisselq
//
7
// Purpose:     Access a Quad SPI flash via a WISHBONE interface.  This
8
//              includes both read and write (and erase) commands to the SPI
9
//              flash.  All read/write commands are accomplished using the
10
//              high speed (4-bit) interface.  Further, the device will be
11
//              left/kept in the 4-bit read interface mode between accesses,
12
//              for a minimum read latency.
13
//
14 3 dgisselq
//      Wishbone Registers (See spec sheet for more detail):
15 2 dgisselq
//      0: local config(r) / erase commands(w) / deep power down cmds / etc.
16
//      R: (Write in Progress), (dirty-block), (spi_port_busy), 1'b0, 9'h00,
17
//              { last_erased_sector, 14'h00 } if (WIP)
18
//              else { current_sector_being_erased, 14'h00 }
19
//              current if write in progress, last if written
20
//      W: (1'b1 to erase), (12'h ignored), next_erased_block, 14'h ignored)
21 3 dgisselq
//      1: Configuration register
22
//      2: Status register (R/w)
23
//      3: Read ID (read only)
24 2 dgisselq
//      (19 bits): Data (R/w, but expect writes to take a while)
25
//              
26
//
27
// Creator:     Dan Gisselquist
28 8 dgisselq
//              Gisselquist Technology, LLC
29 2 dgisselq
//
30 3 dgisselq
///////////////////////////////////////////////////////////////////////////
31 2 dgisselq
//
32 3 dgisselq
// Copyright (C) 2015, Gisselquist Technology, LLC
33 2 dgisselq
//
34 3 dgisselq
// This program is free software (firmware): you can redistribute it and/or
35
// modify it under the terms of  the GNU General Public License as published
36
// by the Free Software Foundation, either version 3 of the License, or (at
37
// your option) any later version.
38
//
39
// This program is distributed in the hope that it will be useful, but WITHOUT
40
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
41
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
42
// for more details.
43
//
44
// You should have received a copy of the GNU General Public License along
45
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
46
// target there if the PDF file isn't present.)  If not, see
47
// <http://www.gnu.org/licenses/> for a copy.
48
//
49
// License:     GPL, v3, as defined and found on www.gnu.org,
50
//              http://www.gnu.org/licenses/gpl.html
51
//
52
//
53
///////////////////////////////////////////////////////////////////////////
54 7 dgisselq
//
55
`include "flash_config.v"
56
//
57 2 dgisselq
`define WBQSPI_RESET            0
58 4 dgisselq
`define WBQSPI_RESET_QUADMODE   1
59 2 dgisselq
`define WBQSPI_IDLE             2
60
`define WBQSPI_RDIDLE           3       // Idle, but in fast read mode
61
`define WBQSPI_WBDECODE         4
62 7 dgisselq
`define WBQSPI_RD_DUMMY         5
63
`define WBQSPI_QRD_ADDRESS      6
64
`define WBQSPI_QRD_DUMMY        7
65
`define WBQSPI_READ_CMD         8
66
`define WBQSPI_READ_DATA        9
67
`define WBQSPI_WAIT_TIL_RDIDLE  10
68
`define WBQSPI_READ_ID_CMD      11
69
`define WBQSPI_READ_ID          12
70
`define WBQSPI_READ_STATUS      13
71
`define WBQSPI_READ_CONFIG      14
72
`define WBQSPI_WAIT_TIL_IDLE    15
73
//
74
//
75
`ifndef READ_ONLY
76
//
77
`define WBQSPI_WAIT_WIP_CLEAR   16
78
`define WBQSPI_CHECK_WIP_CLEAR  17
79
`define WBQSPI_CHECK_WIP_DONE   18
80
`define WBQSPI_WEN              19
81
`define WBQSPI_PP               20      // Program page
82
`define WBQSPI_QPP              21      // Program page, 4 bit mode
83
`define WBQSPI_WR_DATA          22
84
`define WBQSPI_WR_BUS_CYCLE     23
85
`define WBQSPI_WRITE_STATUS     24
86
`define WBQSPI_WRITE_CONFIG     25
87
`define WBQSPI_ERASE_WEN        26
88
`define WBQSPI_ERASE_CMD        27
89
`define WBQSPI_ERASE_BLOCK      28
90
`define WBQSPI_CLEAR_STATUS     29
91
`define WBQSPI_IDLE_CHECK_WIP   30
92
//
93
`endif
94 2 dgisselq
 
95
module  wbqspiflash(i_clk_100mhz,
96
                // Internal wishbone connections
97
                i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, i_wb_we,
98
                i_wb_addr, i_wb_data,
99
                // Wishbone return values
100
                o_wb_ack, o_wb_stall, o_wb_data,
101
                // Quad Spi connections to the external device
102
                o_qspi_sck, o_qspi_cs_n, o_qspi_mod, o_qspi_dat, i_qspi_dat,
103 3 dgisselq
                o_interrupt);
104 7 dgisselq
        parameter       ADDRESS_WIDTH=22;
105 2 dgisselq
        input                   i_clk_100mhz;
106
        // Wishbone, inputs first
107
        input                   i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, i_wb_we;
108 7 dgisselq
        input           [(ADDRESS_WIDTH-3):0]    i_wb_addr;
109 2 dgisselq
        input           [31:0]   i_wb_data;
110
        // then outputs
111
        output  reg             o_wb_ack;
112
        output  reg             o_wb_stall;
113
        output  reg     [31:0]   o_wb_data;
114
        // Quad SPI control wires
115
        output  wire            o_qspi_sck, o_qspi_cs_n;
116
        output  wire    [1:0]    o_qspi_mod;
117
        output  wire    [3:0]    o_qspi_dat;
118
        input           [3:0]    i_qspi_dat;
119
        // Interrupt line
120
        output  reg             o_interrupt;
121 7 dgisselq
        // output       wire    [31:0]  o_debug;
122 2 dgisselq
 
123
        reg             spi_wr, spi_hold, spi_spd, spi_dir;
124
        reg     [31:0]   spi_in;
125
        reg     [1:0]    spi_len;
126
        wire    [31:0]   spi_out;
127
        wire            spi_valid, spi_busy;
128 4 dgisselq
        wire            w_qspi_sck, w_qspi_cs_n;
129
        wire    [3:0]    w_qspi_dat;
130
        wire    [1:0]    w_qspi_mod;
131 7 dgisselq
        // wire [22:0]  spi_dbg;
132 2 dgisselq
        llqspi  lldriver(i_clk_100mhz,
133
                        spi_wr, spi_hold, spi_in, spi_len, spi_spd, spi_dir,
134
                                spi_out, spi_valid, spi_busy,
135 4 dgisselq
                        w_qspi_sck, w_qspi_cs_n, w_qspi_mod, w_qspi_dat,
136 3 dgisselq
                                i_qspi_dat);
137 2 dgisselq
 
138
        // Erase status tracking
139
        reg             write_in_progress, write_protect;
140 7 dgisselq
        reg     [(ADDRESS_WIDTH-17):0]   erased_sector;
141 2 dgisselq
        reg             dirty_sector;
142
        initial begin
143
                write_in_progress = 1'b0;
144 7 dgisselq
                erased_sector = 0;
145 2 dgisselq
                dirty_sector  = 1'b1;
146
                write_protect = 1'b1;
147
        end
148
 
149
        reg     [7:0]    last_status;
150
        reg             quad_mode_enabled;
151 4 dgisselq
        reg             spif_cmd, spif_override;
152 7 dgisselq
        reg     [(ADDRESS_WIDTH-3):0]    spif_addr;
153 2 dgisselq
        reg     [31:0]   spif_data;
154
        reg     [5:0]    state;
155
        reg             spif_ctrl, spif_req;
156 7 dgisselq
        wire    [(ADDRESS_WIDTH-17):0]   spif_sector;
157
        assign  spif_sector = spif_addr[(ADDRESS_WIDTH-3):14];
158 2 dgisselq
 
159 7 dgisselq
        // assign       o_debug = { spi_wr, spi_spd, spi_hold, state, spi_dbg };
160
 
161 2 dgisselq
        initial state = `WBQSPI_RESET;
162
        initial o_wb_ack   = 1'b0;
163
        initial o_wb_stall = 1'b1;
164
        initial spi_wr     = 1'b0;
165
        initial spi_len    = 2'b00;
166
        initial quad_mode_enabled = 1'b0;
167
        initial o_interrupt = 1'b0;
168
        always @(posedge i_clk_100mhz)
169 4 dgisselq
        begin
170
        spif_override <= 1'b0;
171 2 dgisselq
        if (state == `WBQSPI_RESET)
172
        begin
173
                // From a reset, we should
174
                //      Enable the Quad I/O mode
175
                //      Disable the Write protection bits in the status register
176
                //      Chip should already be up and running, so we can start
177
                //      immediately ....
178
                o_wb_ack <= 1'b0;
179
                o_wb_stall <= 1'b1;
180 4 dgisselq
                spi_wr   <= 1'b0;
181 2 dgisselq
                spi_hold <= 1'b0;
182
                spi_spd  <= 1'b0;
183
                spi_dir  <= 1'b0;
184
                last_status <= 8'h00;
185 4 dgisselq
                state <= `WBQSPI_RESET_QUADMODE;
186 2 dgisselq
                spif_req <= 1'b0;
187 4 dgisselq
                spif_override <= 1'b1;
188
                last_status <= 8'hfc; //
189
                        // This guarantees that we aren't starting in quad
190
                        // I/O mode, where the FPGA configuration scripts may
191
                        // have left us.
192
        end else if (state == `WBQSPI_RESET_QUADMODE)
193 2 dgisselq
        begin
194 4 dgisselq
                // Okay, so here's the problem: we don't know whether or not
195
                // the Xilinx loader started us up in Quad Read I/O idle mode.
196
                // So, thus we need to 
197
                // Not ready to handle the bus yet, so stall any requests
198
                o_wb_ack   <= 1'b0;
199
                o_wb_stall <= 1'b1;
200
 
201
                // Do something ...
202
                if (last_status == 8'h00)
203 2 dgisselq
                begin
204 4 dgisselq
                        spif_override <= 1'b0;
205
                        state <= `WBQSPI_IDLE;
206
                end else begin
207
                        last_status <= last_status - 8'h1;
208
                        spif_override <= 1'b1;
209
                        spif_cmd  <= last_status[3]; // Toggle CS_n
210
                        spif_ctrl <= last_status[0]; // Toggle clock too
211 2 dgisselq
                end
212
        end else if (state == `WBQSPI_IDLE)
213
        begin
214
                o_interrupt <= 1'b0;
215
                o_wb_stall <= 1'b0;
216
                o_wb_ack <= 1'b0;
217
                spif_cmd   <= i_wb_we;
218
                spif_addr  <= i_wb_addr;
219
                spif_data  <= i_wb_data;
220
                spif_ctrl  <= (i_wb_ctrl_stb)&&(~i_wb_data_stb);
221
                spif_req   <= (i_wb_ctrl_stb)||(i_wb_data_stb);
222
                spi_wr <= 1'b0; // Keep the port idle, unless told otherwise
223
                spi_hold <= 1'b0;
224
                spi_spd  <= 1'b0;
225
                spi_dir <= 1'b0; // Write (for now, 'cause of cmd)
226
                // Data register access
227
                if ((i_wb_data_stb)&&(i_wb_cyc))
228
                begin
229
 
230
                        if (i_wb_we) // Request to write a page
231
                        begin
232 7 dgisselq
`ifdef  READ_ONLY
233
                                o_wb_ack <= 1'b1;
234
                                o_wb_stall <= 1'b0;
235
                        end else
236
`else
237 2 dgisselq
                                if((~write_protect)&&(~write_in_progress))
238
                                begin // 00
239
                                        spi_wr <= 1'b1;
240
                                        spi_len <= 2'b00; // 8 bits
241
                                        // Send a write enable command
242
                                        spi_in <= { 8'h06, 24'h00 };
243
                                        state <= `WBQSPI_WEN;
244
 
245
                                        o_wb_ack <= 1'b0;
246
                                        o_wb_stall <= 1'b1;
247
                                end else if (write_protect)
248
                                begin // whether or not write-in_progress ...
249
                                        // Do nothing on a write protect
250
                                        // violation
251
                                        //
252
                                        o_wb_ack <= 1'b1;
253
                                        o_wb_stall <= 1'b0;
254
                                end else begin // write is in progress, wait
255
                                        // for it to complete
256
                                        state <= `WBQSPI_WAIT_WIP_CLEAR;
257
                                        o_wb_ack <= 1'b0;
258
                                        o_wb_stall <= 1'b1;
259
                                end
260
                        end else if (~write_in_progress)
261 7 dgisselq
`endif
262 2 dgisselq
                        begin // Read access, normal mode(s)
263
                                o_wb_ack   <= 1'b0;
264
                                o_wb_stall <= 1'b1;
265
                                spi_wr     <= 1'b1;     // Write cmd to device
266
                                if (quad_mode_enabled)
267
                                begin
268 7 dgisselq
                                        spi_in <= { 8'heb,
269
                                                {(24-ADDRESS_WIDTH){1'b0}},
270
                                                i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
271 2 dgisselq
                                        state <= `WBQSPI_QRD_ADDRESS;
272
                                        spi_len    <= 2'b00; // single byte, cmd only
273
                                end else begin
274 7 dgisselq
                                        spi_in <= { 8'h0b,
275
                                                {(24-ADDRESS_WIDTH){1'b0}},
276
                                                i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
277 2 dgisselq
                                        state <= `WBQSPI_RD_DUMMY;
278
                                        spi_len    <= 2'b11; // cmd+addr,32bits
279
                                end
280 7 dgisselq
`ifndef READ_ONLY
281 2 dgisselq
                        end else begin
282
                                // A write is in progress ... need to stall
283
                                // the bus until the write is complete.
284
                                state <= `WBQSPI_WAIT_WIP_CLEAR;
285
                                o_wb_ack   <= 1'b0;
286
                                o_wb_stall <= 1'b1;
287 7 dgisselq
`endif
288 2 dgisselq
                        end
289
                end else if ((i_wb_cyc)&&(i_wb_ctrl_stb)&&(i_wb_we))
290
                begin
291 7 dgisselq
`ifdef  READ_ONLY
292
                        o_wb_ack   <= 1'b1;
293
                        o_wb_stall <= 1'b0;
294
`else
295 2 dgisselq
                        o_wb_stall <= 1'b1;
296
                        case(i_wb_addr[1:0])
297
                        2'b00: begin // Erase command register
298
                                write_protect <= ~i_wb_data[28];
299
                                o_wb_stall <= 1'b0;
300
 
301
                                if((i_wb_data[31])&&(~write_in_progress))
302
                                begin
303
                                        // Command an erase--ack it immediately
304
 
305
                                        o_wb_ack <= 1'b1;
306
                                        o_wb_stall <= 1'b0;
307
 
308
                                        if ((i_wb_data[31])&&(~write_protect))
309
                                        begin
310
                                                spi_wr <= 1'b1;
311
                                                spi_len <= 2'b00;
312
                                                // Send a write enable command
313
                                                spi_in <= { 8'h06, 24'h00 };
314
                                                state <= `WBQSPI_ERASE_CMD;
315
                                                o_wb_stall <= 1'b1;
316
                                        end
317
                                end else if (i_wb_data[31])
318
                                begin
319
                                        state <= `WBQSPI_WAIT_WIP_CLEAR;
320
                                        o_wb_ack   <= 1'b1;
321
                                        o_wb_stall <= 1'b1;
322
                                end else
323
                                        o_wb_ack   <= 1'b1;
324
                                        o_wb_stall <= 1'b0;
325
                                end
326
                        2'b01: begin
327
                                // Write the configuration register
328
                                o_wb_ack <= 1'b1;
329
                                o_wb_stall <= 1'b1;
330
 
331
                                // Need to send a write enable command first
332
                                spi_wr <= 1'b1;
333
                                spi_len <= 2'b00; // 8 bits
334
                                // Send a write enable command
335
                                spi_in <= { 8'h06, 24'h00 };
336
                                state <= `WBQSPI_WRITE_CONFIG;
337
                                end
338
                        2'b10: begin
339
                                // Write the status register
340
                                o_wb_ack <= 1'b1; // Ack immediately
341
                                o_wb_stall <= 1'b1; // Stall other cmds
342
                                // Need to send a write enable command first
343
                                spi_wr <= 1'b1;
344
                                spi_len <= 2'b00; // 8 bits
345
                                // Send a write enable command
346
                                spi_in <= { 8'h06, 24'h00 };
347
                                state <= `WBQSPI_WRITE_STATUS;
348
                                end
349
                        2'b11: begin // Write the ID register??? makes no sense
350
                                o_wb_ack <= 1'b1;
351
                                o_wb_stall <= 1'b0;
352
                                end
353
                        endcase
354 7 dgisselq
`endif
355 2 dgisselq
                end else if ((i_wb_cyc)&&(i_wb_ctrl_stb)) // &&(~i_wb_we))
356
                begin
357
                        case(i_wb_addr[1:0])
358
                        2'b00: begin // Read local register
359
                                if (write_in_progress) // Read status
360
                                begin// register, is write still in progress?
361
                                        state <= `WBQSPI_READ_STATUS;
362
                                        spi_wr <= 1'b1;
363
                                        spi_len <= 2'b01;// 8 bits out, 8 bits in
364
                                        spi_in <= { 8'h05, 24'h00};
365
 
366
                                        o_wb_ack <= 1'b0;
367
                                        o_wb_stall <= 1'b1;
368
                                end else begin // Return w/o talking to device
369
                                        o_wb_ack <= 1'b1;
370
                                        o_wb_stall <= 1'b0;
371
                                        o_wb_data <= { write_in_progress,
372
                                                dirty_sector, spi_busy,
373
                                                ~write_protect,
374
                                                quad_mode_enabled,
375 7 dgisselq
                                                {(29-ADDRESS_WIDTH){1'b0}},
376 2 dgisselq
                                                erased_sector, 14'h000 };
377
                                end end
378
                        2'b01: begin // Read configuration register
379
                                state <= `WBQSPI_READ_CONFIG;
380
                                spi_wr <= 1'b1;
381
                                spi_len <= 2'b01;
382
                                spi_in <= { 8'h35, 24'h00};
383
 
384
                                o_wb_ack <= 1'b0;
385
                                o_wb_stall <= 1'b1;
386
                                end
387
                        2'b10: begin // Read status register
388
                                state <= `WBQSPI_READ_STATUS;
389
                                spi_wr <= 1'b1;
390
                                spi_len <= 2'b01; // 8 bits out, 8 bits in
391
                                spi_in <= { 8'h05, 24'h00};
392
 
393
                                o_wb_ack <= 1'b0;
394
                                o_wb_stall <= 1'b1;
395
                                end
396
                        2'b11: begin // Read ID register
397
                                state <= `WBQSPI_READ_ID_CMD;
398
                                spi_wr <= 1'b1;
399
                                spi_len <= 2'b00;
400
                                spi_in <= { 8'h9f, 24'h00};
401
 
402
                                o_wb_ack <= 1'b0;
403
                                o_wb_stall <= 1'b1;
404
                                end
405
                        endcase
406 7 dgisselq
`ifndef READ_ONLY
407 2 dgisselq
                end else if ((~i_wb_cyc)&&(write_in_progress))
408
                begin
409
                        state <= `WBQSPI_IDLE_CHECK_WIP;
410
                        spi_wr <= 1'b1;
411
                        spi_len <= 2'b01; // 8 bits out, 8 bits in
412
                        spi_in <= { 8'h05, 24'h00};
413
 
414
                        o_wb_ack <= 1'b0;
415
                        o_wb_stall <= 1'b1;
416 7 dgisselq
`endif
417 2 dgisselq
                end
418
        end else if (state == `WBQSPI_RDIDLE)
419
        begin
420
                spi_wr <= 1'b0;
421
                o_wb_stall <= 1'b0;
422
                o_wb_ack <= 1'b0;
423
                spif_cmd   <= i_wb_we;
424
                spif_addr  <= i_wb_addr;
425
                spif_data  <= i_wb_data;
426
                spif_ctrl  <= (i_wb_ctrl_stb)&&(~i_wb_data_stb);
427
                spif_req   <= (i_wb_ctrl_stb)||(i_wb_data_stb);
428
                spi_hold <= 1'b0;
429
                spi_spd<= 1'b1;
430
                spi_dir <= 1'b0; // Write (for now)
431
                if ((i_wb_cyc)&&(i_wb_data_stb)&&(~i_wb_we))
432
                begin // Continue our read ... send the new address / mode
433
                        o_wb_stall <= 1'b1;
434
                        spi_wr <= 1'b1;
435 4 dgisselq
                        spi_len <= 2'b10; // Write address, but not mode byte
436 7 dgisselq
                        spi_in <= { {(24-ADDRESS_WIDTH){1'b0}},
437
                                        i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00, 8'ha0 };
438 2 dgisselq
                        state <= `WBQSPI_QRD_DUMMY;
439
                end else if((i_wb_cyc)&&(i_wb_ctrl_stb)&&(~i_wb_we)&&(i_wb_addr[1:0] == 2'b00))
440
                begin
441
                        // A local read that doesn't touch the device, so leave
442
                        // the device in its current state
443
                        o_wb_stall <= 1'b0;
444
                        o_wb_ack <= 1'b1;
445
                        o_wb_data <= { write_in_progress,
446
                                        dirty_sector, spi_busy,
447
                                        ~write_protect,
448
                                        quad_mode_enabled,
449 7 dgisselq
                                        {(29-ADDRESS_WIDTH){1'b0}},
450 2 dgisselq
                                        erased_sector, 14'h000 };
451
                end else if((i_wb_cyc)&&((i_wb_ctrl_stb)||(i_wb_data_stb)))
452
                begin // Need to release the device from quad mode for all else
453
                        o_wb_ack   <= 1'b0;
454
                        o_wb_stall <= 1'b1;
455
                        spi_wr <= 1'b1;
456
                        spi_len <= 2'b11;
457
                        spi_in <= 32'h00;
458
                        state <= `WBQSPI_WBDECODE;
459
                end
460
        end else if (state == `WBQSPI_WBDECODE)
461
        begin
462
                // We were in quad SPI read mode, and had to get out.
463
                // Now we've got a command (not data read) to read and
464
                // execute.  Accomplish what we would've done while in the
465
                // IDLE state here, save only that we don't have to worry
466
                // about data reads, and we need to operate on a stored
467
                // version of the bus command
468
                o_wb_stall <= 1'b1;
469
                o_wb_ack <= 1'b0;
470
                spi_wr <= 1'b0; // Keep the port idle, unless told otherwise
471
                spi_hold <= 1'b0;
472
                spi_spd <= 1'b0;
473
                spi_dir <= 1'b0;
474
                spif_req<= (spif_req) && (i_wb_cyc);
475
                if ((~spi_busy)&&(o_qspi_cs_n)&&(~spi_wr)) // only in full idle ...
476
                begin
477
                        // Data register access
478
                        if (~spif_ctrl)
479
                        begin
480
                                if (spif_cmd) // Request to write a page
481
                                begin
482 7 dgisselq
`ifdef  READ_ONLY
483
                                        o_wb_ack <= spif_req;
484
                                        o_wb_stall <= 1'b0;
485
                                        state <= `WBQSPI_IDLE;
486
`else
487 2 dgisselq
                                        if((~write_protect)&&(~write_in_progress))
488
                                        begin // 00
489
                                                spi_wr <= 1'b1;
490
                                                spi_len <= 2'b00; // 8 bits
491
                                                // Send a write enable command
492
                                                spi_in <= { 8'h06, 24'h00 };
493
                                                state <= `WBQSPI_WEN;
494
 
495
                                                o_wb_ack <= 1'b0;
496
                                                o_wb_stall <= 1'b1;
497
                                        end else if (write_protect)
498
                                        begin // whether or not write-in_progress ...
499
                                                // Do nothing on a write protect
500
                                                // violation
501
                                                //
502
                                                o_wb_ack <= spif_req;
503
                                                o_wb_stall <= 1'b0;
504
                                                state <= `WBQSPI_IDLE;
505
                                        end else begin // write is in progress, wait
506
                                                // for it to complete
507
                                                state <= `WBQSPI_WAIT_WIP_CLEAR;
508
                                                o_wb_ack <= 1'b0;
509
                                                o_wb_stall <= 1'b1;
510
                                        end
511
                                // end else if (~write_in_progress) // always true
512
                                // but ... we wouldn't get here on a normal read access
513 7 dgisselq
`endif
514 2 dgisselq
                                end else begin
515 7 dgisselq
                                        // Something's wrong, we should never
516
                                        //   get here
517 2 dgisselq
                                        // Attempt to go to idle to recover
518
                                        state <= `WBQSPI_IDLE;
519
                                end
520
                        end else if ((spif_ctrl)&&(spif_cmd))
521
                        begin
522 7 dgisselq
`ifdef  READ_ONLY
523
                                o_wb_ack   <= spif_req;
524
                                o_wb_stall <= 1'b0;
525
                                state <= `WBQSPI_IDLE;
526
`else
527 2 dgisselq
                                o_wb_stall <= 1'b1;
528
                                case(spif_addr[1:0])
529
                                2'b00: begin // Erase command register
530
                                        o_wb_ack   <= spif_req;
531
                                        o_wb_stall <= 1'b0;
532
                                        state <= `WBQSPI_IDLE;
533
                                        write_protect <= ~spif_data[28];
534
                                        // Are we commanding an erase?
535
                                        // We're in read mode, writes cannot
536
                                        // be in progress, so ...
537
                                        if (spif_data[31]) // Command an erase
538
                                        begin
539
                                                // Since we're not going back
540
                                                // to IDLE, we must stall the
541
                                                // bus here
542
                                                o_wb_stall <= 1'b1;
543
                                                spi_wr <= 1'b1;
544
                                                spi_len <= 2'b00;
545
                                                // Send a write enable command
546
                                                spi_in <= { 8'h06, 24'h00 };
547
                                                state <= `WBQSPI_ERASE_CMD;
548
                                        end end
549
                                2'b01: begin
550
                                        // Write the configuration register
551
                                        o_wb_ack <= spif_req;
552
                                        o_wb_stall <= 1'b1;
553
 
554
                                        // Need to send a write enable command first
555
                                        spi_wr <= 1'b1;
556
                                        spi_len <= 2'b00; // 8 bits
557
                                        // Send a write enable command
558
                                        spi_in <= { 8'h06, 24'h00 };
559
                                        state <= `WBQSPI_WRITE_CONFIG;
560
                                        end
561
                                2'b10: begin
562
                                        // Write the status register
563
                                        o_wb_ack <= spif_req; // Ack immediately
564
                                        o_wb_stall <= 1'b1; // Stall other cmds
565
                                        // Need to send a write enable command first
566
                                        spi_wr <= 1'b1;
567
                                        spi_len <= 2'b00; // 8 bits
568
                                        // Send a write enable command
569
                                        spi_in <= { 8'h06, 24'h00 };
570
                                        state <= `WBQSPI_WRITE_STATUS;
571
                                        end
572
                                2'b11: begin // Write the ID register??? makes no sense
573
                                        o_wb_ack <= spif_req;
574
                                        o_wb_stall <= 1'b0;
575
                                        state <= `WBQSPI_IDLE;
576
                                        end
577
                                endcase
578 7 dgisselq
`endif
579 2 dgisselq
                        end else begin // on (~spif_we)
580
                                case(spif_addr[1:0])
581
                                2'b00: begin // Read local register
582
                                        // Nonsense case--would've done this
583
                                        // already
584
                                        state <= `WBQSPI_IDLE;
585
                                        o_wb_ack <= spif_req;
586
                                        o_wb_stall <= 1'b0;
587
                                        end
588
                                2'b01: begin // Read configuration register
589
                                        state <= `WBQSPI_READ_CONFIG;
590
                                        spi_wr <= 1'b1;
591
                                        spi_len <= 2'b01;
592
                                        spi_in <= { 8'h35, 24'h00};
593
 
594
                                        o_wb_ack <= 1'b0;
595
                                        o_wb_stall <= 1'b1;
596
                                        end
597
                                2'b10: begin // Read status register
598
                                        state <= `WBQSPI_READ_STATUS;
599
                                        spi_wr <= 1'b1;
600
                                        spi_len <= 2'b01; // 8 bits out, 8 bits in
601
                                        spi_in <= { 8'h05, 24'h00};
602
 
603
                                        o_wb_ack <= 1'b0;
604
                                        o_wb_stall <= 1'b1;
605
                                        end
606
                                2'b11: begin // Read ID register
607
                                        state <= `WBQSPI_READ_ID_CMD;
608
                                        spi_wr <= 1'b1;
609
                                        spi_len <= 2'b00;
610
                                        spi_in <= { 8'h9f, 24'h00};
611
 
612
                                        o_wb_ack <= 1'b0;
613
                                        o_wb_stall <= 1'b1;
614
                                        end
615
                                endcase
616
                        end
617
                end
618 7 dgisselq
//
619
//
620
//      READ DATA section: for both data and commands
621
//
622 2 dgisselq
        end else if (state == `WBQSPI_RD_DUMMY)
623
        begin
624
                o_wb_ack   <= 1'b0;
625
                o_wb_stall <= 1'b1;
626
 
627
                spi_wr <= 1'b1; // Non-stop
628
                // Need to read one byte of dummy data,
629
                // just to consume 8 clocks
630
                spi_in <= { 8'h00, 24'h00 };
631
                spi_len <= 2'b00; // Read 8 bits
632
                spi_spd <= 1'b0;
633
                spi_hold <= 1'b0;
634
                spif_req<= (spif_req) && (i_wb_cyc);
635
 
636
                if ((~spi_busy)&&(~o_qspi_cs_n))
637
                        // Our command was accepted
638
                        state <= `WBQSPI_READ_CMD;
639
        end else if (state == `WBQSPI_QRD_ADDRESS)
640
        begin
641
                // We come in here immediately upon issuing a QRD read
642
                // command (8-bits), but we have to pause to give the
643
                // address (24-bits) and mode (8-bits) in quad speed.
644
                o_wb_ack   <= 1'b0;
645
                o_wb_stall <= 1'b1;
646
 
647
                spi_wr <= 1'b1; // Non-stop
648 7 dgisselq
                spi_in <= { {(24-ADDRESS_WIDTH){1'b0}},
649
                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00, 8'ha0 };
650 4 dgisselq
                spi_len <= 2'b10; // Write address, not mode byte
651 2 dgisselq
                spi_spd <= 1'b1;
652
                spi_dir <= 1'b0; // Still writing
653
                spi_hold <= 1'b0;
654
                spif_req<= (spif_req) && (i_wb_cyc);
655
 
656
                if ((~spi_busy)&&(spi_spd))
657
                        // Our command was accepted
658
                        state <= `WBQSPI_QRD_DUMMY;
659
        end else if (state == `WBQSPI_QRD_DUMMY)
660
        begin
661
                o_wb_ack   <= 1'b0;
662
                o_wb_stall <= 1'b1;
663
 
664
                spi_wr <= 1'b1; // Non-stop
665
                spi_in <= { 8'ha0, 24'h00 }; // Mode byte, then 2 bytes dummy
666 9 dgisselq
                spi_len <= 2'b10; // Write 24 bits
667 2 dgisselq
                spi_spd <= 1'b1;
668
                spi_dir <= 1'b0; // Still writing
669
                spi_hold <= 1'b0;
670
                spif_req<= (spif_req) && (i_wb_cyc);
671
 
672
                if ((~spi_busy)&&(spi_in[31:28] == 4'ha))
673
                        // Our command was accepted
674
                        state <= `WBQSPI_READ_CMD;
675
        end else if (state == `WBQSPI_READ_CMD)
676
        begin // Issue our first command to read 32 bits.
677
                o_wb_ack   <= 1'b0;
678
                o_wb_stall <= 1'b1;
679
 
680
                spi_wr <= 1'b1;
681
                spi_in <= { 8'hff, 24'h00 }; // Empty
682
                spi_len <= 2'b11; // Read 32 bits
683
                spi_dir <= 1'b1; // Now reading
684
                spi_hold <= 1'b0;
685
                spif_req<= (spif_req) && (i_wb_cyc);
686
                if ((spi_valid)&&(spi_len == 2'b11))
687
                        state <= `WBQSPI_READ_DATA;
688
        end else if (state == `WBQSPI_READ_DATA)
689
        begin
690
                // Pipelined read support
691
                spi_wr <=((i_wb_cyc)&&(i_wb_data_stb)&&(~i_wb_we)&&(i_wb_addr== (spif_addr+1)));
692
                spi_in <= 32'h00;
693
                spi_len <= 2'b11;
694
                // Don't adjust the speed here, it was set in the setup
695 4 dgisselq
                spi_dir <= 1'b1;        // Now we get to read
696
                // Don't let the device go to idle until the bus cycle ends.
697
                //      This actually prevents a *really* nasty race condition,
698
                //      where the strobe comes in after the lower level device
699
                //      has decided to stop waiting.  The write is then issued,
700
                //      but no one is listening.  By leaving the device open,
701
                //      the device is kept in a state where a valid strobe
702
                //      here will be useful.  Of course, we don't accept
703
                //      all commands, just reads.  Further, the strobe needs
704
                //      to be high for two clocks cycles without changing
705
                //      anything on the bus--one for us to notice it and pull
706
                //      our head out of the sand, and a second for whoever
707
                //      owns the bus to realize their command went through.
708
                spi_hold <= 1'b1;
709 2 dgisselq
                spif_req<= (spif_req) && (i_wb_cyc);
710
                if ((spi_valid)&&(~spi_in[31]))
711
                begin // Single pulse acknowledge and write data out
712
                        o_wb_ack <= spif_req;
713
                        o_wb_stall <= (~spi_wr);
714
                        // adjust endian-ness to match the PC
715
                        o_wb_data <= { spi_out[7:0], spi_out[15:8],
716
                                spi_out[23:16], spi_out[31:24] };
717
                        state <= (spi_wr)?`WBQSPI_READ_DATA
718
                                : ((spi_spd) ? `WBQSPI_WAIT_TIL_RDIDLE : `WBQSPI_WAIT_TIL_IDLE);
719
                        spif_req <= spi_wr;
720 4 dgisselq
                        spi_hold <= (~spi_wr);
721 2 dgisselq
                        if (spi_wr)
722
                                spif_addr <= i_wb_addr;
723 4 dgisselq
                end else if (~i_wb_cyc)
724
                begin // FAIL SAFE: If the bus cycle ends, forget why we're
725
                        // here, just go back to idle
726
                        state <= ((spi_spd) ? `WBQSPI_WAIT_TIL_RDIDLE : `WBQSPI_WAIT_TIL_IDLE);
727
                        spi_hold <= 1'b0;
728
                        o_wb_ack <= 1'b0;
729
                        o_wb_stall <= 1'b1;
730 2 dgisselq
                end else begin
731
                        o_wb_ack <= 1'b0;
732
                        o_wb_stall <= 1'b1;
733
                end
734
        end else if (state == `WBQSPI_WAIT_TIL_RDIDLE)
735
        begin // Wait 'til idle, but then go to fast read idle instead of full
736
                spi_wr     <= 1'b0;     // idle
737
                spi_hold   <= 1'b0;
738
                o_wb_stall <= 1'b1;
739
                o_wb_ack   <= 1'b0;
740
                spif_req   <= 1'b0;
741
                if ((~spi_busy)&&(o_qspi_cs_n)&&(~spi_wr)) // Wait for a full
742
                begin // clearing of the SPI port before moving on
743
                        state <= `WBQSPI_RDIDLE;
744
                        o_wb_stall <= 1'b0;
745
                        o_wb_ack   <= 1'b0;// Shouldn't be acking anything here
746
                end
747
        end else if (state == `WBQSPI_READ_ID_CMD)
748
        begin // We came into here immediately after issuing a 0x9f command
749
                // Now we need to read 32 bits of data.  Result should be
750
                // 0x0102154d (8'h manufacture ID, 16'h device ID, followed
751
                // by the number of extended bytes available 8'h4d).
752
                o_wb_ack <= 1'b0;
753
                o_wb_stall<= 1'b1;
754
 
755
                spi_wr <= 1'b1; // No data to send, but need four bytes, since
756
                spi_len <= 2'b11; // 32 bits of data are ... useful
757
                spi_in <= 32'h00; // Irrelevant
758
                spi_spd <= 1'b0; // Slow speed
759
                spi_dir <= 1'b1; // Reading
760
                spi_hold <= 1'b0;
761
                spif_req <= (spif_req) && (i_wb_cyc);
762
                if ((~spi_busy)&&(~o_qspi_cs_n)&&(spi_len == 2'b11))
763
                        // Our command was accepted, now go read the result
764
                        state <= `WBQSPI_READ_ID;
765
        end else if (state == `WBQSPI_READ_ID)
766
        begin
767
                o_wb_ack <= 1'b0; // Assuming we're still waiting
768
                o_wb_stall <= 1'b1;
769
 
770 4 dgisselq
                spi_wr <= 1'b0; // No more writes, we've already written the cmd
771 2 dgisselq
                spi_hold <= 1'b0;
772
                spif_req <= (spif_req) && (i_wb_cyc);
773
 
774
                // Here, we just wait until the result comes back
775
                // The problem is, the result may be the previous result.
776
                // So we use spi_len as an indicator
777
                spi_len <= 2'b00;
778
                if((spi_valid)&&(spi_len==2'b00))
779
                begin // Put the results out as soon as possible
780
                        o_wb_data <= spi_out[31:0];
781
                        o_wb_ack <= spif_req;
782
                        spif_req <= 1'b0;
783 4 dgisselq
                end else if ((~spi_busy)&&(o_qspi_cs_n))
784 2 dgisselq
                begin
785
                        state <= `WBQSPI_IDLE;
786
                        o_wb_stall <= 1'b0;
787
                end
788
        end else if (state == `WBQSPI_READ_STATUS)
789
        begin // We enter after the command has been given, for now just
790
                // read and return
791
                spi_wr <= 1'b0;
792
                o_wb_ack <= 1'b0;
793
                spi_hold <= 1'b0;
794
                spif_req <= (spif_req) && (i_wb_cyc);
795
                if (spi_valid)
796
                begin
797
                        o_wb_ack <= spif_req;
798
                        o_wb_stall <= 1'b1;
799
                        spif_req <= 1'b0;
800
                        last_status <= spi_out[7:0];
801
                        write_in_progress <= spi_out[0];
802
                        if (spif_addr[1:0] == 2'b00) // Local read, checking
803
                        begin // status, 'cause we're writing
804
                                o_wb_data <= { spi_out[0],
805
                                        dirty_sector, spi_busy,
806
                                        ~write_protect,
807
                                        quad_mode_enabled,
808 7 dgisselq
                                        {(29-ADDRESS_WIDTH){1'b0}},
809 2 dgisselq
                                        erased_sector, 14'h000 };
810
                        end else begin
811
                                o_wb_data <= { 24'h00, spi_out[7:0] };
812
                        end
813
                end
814
 
815
                if ((~spi_busy)&&(~spi_wr))
816
                        state <= `WBQSPI_IDLE;
817
        end else if (state == `WBQSPI_READ_CONFIG)
818
        begin // We enter after the command has been given, for now just
819
                // read and return
820
                spi_wr <= 1'b0;
821
                o_wb_ack <= 1'b0;
822
                o_wb_stall <= 1'b1;
823
                spi_hold <= 1'b0;
824
                spif_req <= (spif_req) && (i_wb_cyc);
825
 
826
                if (spi_valid)
827
                begin
828
                        o_wb_data <= { 24'h00, spi_out[7:0] };
829
                        quad_mode_enabled <= spi_out[1];
830
                end
831
 
832
                if ((~spi_busy)&&(~spi_wr))
833
                begin
834
                        state <= `WBQSPI_IDLE;
835
                        o_wb_ack   <= spif_req;
836
                        o_wb_stall <= 1'b0;
837
                        spif_req <= 1'b0;
838
                end
839 7 dgisselq
 
840
//
841
//
842
//      Write/erase data section
843
//
844
`ifndef READ_ONLY
845
        end else if (state == `WBQSPI_WAIT_WIP_CLEAR)
846
        begin
847
                o_wb_stall <= 1'b1;
848
                o_wb_ack   <= 1'b0;
849
                spi_wr <= 1'b0;
850
                spif_req<= (spif_req) && (i_wb_cyc);
851
                if (~spi_busy)
852
                begin
853
                        spi_wr   <= 1'b1;
854
                        spi_in   <= { 8'h05, 24'h0000 };
855
                        spi_hold <= 1'b1;
856
                        spi_len  <= 2'b01; // 16 bits write, so we can read 8
857
                        state <= `WBQSPI_CHECK_WIP_CLEAR;
858
                        spi_spd  <= 1'b0; // Slow speed
859
                        spi_dir  <= 1'b0;
860
                end
861
        end else if (state == `WBQSPI_CHECK_WIP_CLEAR)
862
        begin
863
                o_wb_stall <= 1'b1;
864
                o_wb_ack   <= 1'b0;
865
                // Repeat as often as necessary until we are clear
866
                spi_wr <= 1'b1;
867
                spi_in <= 32'h0000; // Values here are actually irrelevant
868
                spi_hold <= 1'b1;
869
                spi_len <= 2'b00; // One byte at a time
870
                spi_spd  <= 1'b0; // Slow speed
871
                spi_dir  <= 1'b0;
872
                spif_req<= (spif_req) && (i_wb_cyc);
873
                if ((spi_valid)&&(~spi_out[0]))
874
                begin
875
                        state <= `WBQSPI_CHECK_WIP_DONE;
876
                        spi_wr   <= 1'b0;
877
                        spi_hold <= 1'b0;
878
                        write_in_progress <= 1'b0;
879
                        last_status <= spi_out[7:0];
880
                end
881
        end else if (state == `WBQSPI_CHECK_WIP_DONE)
882
        begin
883
                o_wb_stall <= 1'b1;
884
                o_wb_ack   <= 1'b0;
885
                // Let's let the SPI port come back to a full idle,
886
                // and the chip select line go low before continuing
887
                spi_wr   <= 1'b0;
888
                spi_len  <= 2'b00;
889
                spi_hold <= 1'b0;
890
                spi_spd  <= 1'b0; // Slow speed
891
                spi_dir  <= 1'b0;
892
                spif_req<= (spif_req) && (i_wb_cyc);
893
                if ((o_qspi_cs_n)&&(~spi_busy)) // Chip select line is high, we can continue
894
                begin
895
                        spi_wr   <= 1'b0;
896
                        spi_hold <= 1'b0;
897
 
898
                        casez({ spif_cmd, spif_ctrl, spif_addr[1:0] })
899
                        4'b00??: begin // Read data from ... somewhere
900
                                spi_wr     <= 1'b1;     // Write cmd to device
901
                                if (quad_mode_enabled)
902
                                begin
903
                                        spi_in <= { 8'heb,
904
                                                {(24-ADDRESS_WIDTH){1'b0}},
905
                                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
906
                                        state <= `WBQSPI_QRD_ADDRESS;
907
                                        // spi_len    <= 2'b00; // single byte, cmd only
908
                                end else begin
909
                                        spi_in <= { 8'h0b,
910
                                                {(24-ADDRESS_WIDTH){1'b0}},
911
                                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
912
                                        state <= `WBQSPI_RD_DUMMY;
913
                                        spi_len    <= 2'b11; // Send cmd and addr
914
                                end end
915
                        4'b10??: begin // Write data to ... anywhere
916
                                spi_wr <= 1'b1;
917
                                spi_len <= 2'b00; // 8 bits
918
                                // Send a write enable command
919
                                spi_in <= { 8'h06, 24'h00 };
920
                                state <= `WBQSPI_WEN;
921
                                end
922
                        4'b0110: begin // Read status register
923
                                state <= `WBQSPI_READ_STATUS;
924
                                spi_wr <= 1'b1;
925
                                spi_len <= 2'b01; // 8 bits out, 8 bits in
926
                                spi_in <= { 8'h05, 24'h00};
927
                                end
928
                        4'b0111: begin
929
                                state <= `WBQSPI_READ_ID_CMD;
930
                                spi_wr <= 1'b1;
931
                                spi_len <= 2'b00;
932
                                spi_in <= { 8'h9f, 24'h00};
933
                                end
934
                        default: begin //
935
                                o_wb_stall <= 1'b1;
936
                                o_wb_ack <= spif_req;
937
                                state <= `WBQSPI_WAIT_TIL_IDLE;
938
                                end
939
                        endcase
940
                // spif_cmd   <= i_wb_we;
941
                // spif_addr  <= i_wb_addr;
942
                // spif_data  <= i_wb_data;
943
                // spif_ctrl  <= (i_wb_ctrl_stb)&&(~i_wb_data_stb);
944
                // spi_wr <= 1'b0; // Keep the port idle, unless told otherwise
945
                end
946
        end else if (state == `WBQSPI_WEN)
947
        begin // We came here after issuing a write enable command
948
                spi_wr <= 1'b0;
949
                o_wb_ack <= 1'b0;
950
                o_wb_stall <= 1'b1;
951
                spif_req<= (spif_req) && (i_wb_cyc);
952
                if ((~spi_busy)&&(o_qspi_cs_n)&&(~spi_wr)) // Let's come to a full stop
953
                        state <= (quad_mode_enabled)?`WBQSPI_QPP:`WBQSPI_PP;
954
                        // state <= `WBQSPI_PP;
955
        end else if (state == `WBQSPI_PP)
956
        begin // We come here under a full stop / full port idle mode
957
                // Issue our command immediately
958
                spi_wr <= 1'b1;
959
                spi_in <= { 8'h02,
960
                                {(24-ADDRESS_WIDTH){1'b0}},
961
                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
962
                spi_len <= 2'b11;
963
                spi_hold <= 1'b1;
964
                spi_spd  <= 1'b0;
965
                spi_dir  <= 1'b0; // Writing
966
                spif_req<= (spif_req) && (i_wb_cyc);
967
 
968
                // Once we get busy, move on
969
                if (spi_busy)
970
                        state <= `WBQSPI_WR_DATA;
971
                if (spif_sector == erased_sector)
972
                        dirty_sector <= 1'b1;
973
        end else if (state == `WBQSPI_QPP)
974
        begin // We come here under a full stop / full port idle mode
975
                // Issue our command immediately
976
                spi_wr <= 1'b1;
977
                spi_in <= { 8'h32,
978
                                {(24-ADDRESS_WIDTH){1'b0}},
979
                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
980
                spi_len <= 2'b11;
981
                spi_hold <= 1'b1;
982
                spi_spd  <= 1'b0;
983
                spi_dir  <= 1'b0; // Writing
984
                spif_req<= (spif_req) && (i_wb_cyc);
985
 
986
                // Once we get busy, move on
987
                if (spi_busy)
988
                begin
989
                        // spi_wr is irrelevant here ...
990
                        // Set the speed value once, but wait til we get busy
991
                        // to do so.
992
                        spi_spd <= 1'b1;
993
                        state <= `WBQSPI_WR_DATA;
994
                end
995
                if (spif_sector == erased_sector)
996
                        dirty_sector <= 1'b1;
997
        end else if (state == `WBQSPI_WR_DATA)
998
        begin
999
                o_wb_stall <= 1'b1;
1000
                o_wb_ack   <= 1'b0;
1001
                spi_wr   <= 1'b1; // write without waiting
1002
                spi_in   <= {
1003
                        spif_data[ 7: 0],
1004
                        spif_data[15: 8],
1005
                        spif_data[23:16],
1006
                        spif_data[31:24] };
1007
                spi_len  <= 2'b11; // Write 4 bytes
1008
                spi_hold <= 1'b1;
1009
                if (~spi_busy)
1010
                begin
1011
                        o_wb_ack <= spif_req; // Ack when command given
1012
                        state <= `WBQSPI_WR_BUS_CYCLE;
1013
                end
1014
                spif_req<= (spif_req) && (i_wb_cyc);
1015
        end else if (state == `WBQSPI_WR_BUS_CYCLE)
1016
        begin
1017
                o_wb_ack <= 1'b0; // Turn off our ack and stall flags
1018
                o_wb_stall <= 1'b1;
1019
                spi_wr <= 1'b0;
1020
                spi_hold <= 1'b1;
1021
                write_in_progress <= 1'b1;
1022
                spif_req<= (spif_req) && (i_wb_cyc);
1023
                if (~i_wb_cyc)
1024
                begin
1025
                        state <= `WBQSPI_WAIT_TIL_IDLE;
1026
                        spi_hold <= 1'b0;
1027
                end else if (spi_wr)
1028
                begin // Give the SPI a chance to get busy on the last write
1029
                        // Do nothing here.
1030
                end else if ((i_wb_data_stb)&&(i_wb_we)
1031
                                &&(i_wb_addr == (spif_addr+1))
1032
                                &&(i_wb_addr[(ADDRESS_WIDTH-3):6]==spif_addr[(ADDRESS_WIDTH-3):6]))
1033
                begin
1034
                        spif_cmd  <= 1'b1;
1035
                        spif_data <= i_wb_data;
1036
                        spif_addr <= i_wb_addr;
1037
                        spif_ctrl  <= 1'b0;
1038
                        spif_req<= 1'b1;
1039
                        // We'll keep the bus stalled on this request
1040
                        // for a while
1041
                        state <= `WBQSPI_WR_DATA;
1042
                        o_wb_ack   <= 1'b0;
1043
                        o_wb_stall <= 1'b0;
1044
                end else if ((i_wb_data_stb|i_wb_ctrl_stb)&&(~o_wb_ack)) // Writing out of bounds
1045
                begin
1046
                        spi_hold <= 1'b0;
1047
                        spi_wr   <= 1'b0;
1048
                        state <= `WBQSPI_WAIT_TIL_IDLE;
1049
                end // Otherwise we stay here
1050 2 dgisselq
        end else if (state == `WBQSPI_WRITE_CONFIG)
1051
        begin // We enter immediately after commanding a WEN
1052
                o_wb_ack   <= 1'b0;
1053
                o_wb_stall <= 1'b1;
1054
 
1055
                spi_len <= 2'b10;
1056
                spi_in <= { 8'h01, last_status, spif_data[7:0], 8'h00 };
1057
                spi_wr <= 1'b0;
1058
                spi_hold <= 1'b0;
1059
                spif_req <= (spif_req) && (i_wb_cyc);
1060
                if ((~spi_busy)&&(~spi_wr))
1061
                begin
1062
                        spi_wr <= 1'b1;
1063
                        state <= `WBQSPI_WAIT_TIL_IDLE;
1064
                        write_in_progress <= 1'b1;
1065
                        quad_mode_enabled <= spif_data[1];
1066
                end
1067
        end else if (state == `WBQSPI_WRITE_STATUS)
1068
        begin // We enter immediately after commanding a WEN
1069
                o_wb_ack   <= 1'b0;
1070
                o_wb_stall <= 1'b1;
1071
 
1072
                spi_len <= 2'b01;
1073
                spi_in <= { 8'h01, spif_data[7:0], 16'h00 };
1074
                // last_status <= i_wb_data[7:0]; // We'll read this in a moment
1075
                spi_wr <= 1'b0;
1076
                spi_hold <= 1'b0;
1077
                spif_req <= (spif_req) && (i_wb_cyc);
1078
                if ((~spi_busy)&&(~spi_wr))
1079
                begin
1080
                        spi_wr <= 1'b1;
1081
                        last_status <= spif_data[7:0];
1082
                        write_in_progress <= 1'b1;
1083
                        if(((last_status[6])||(last_status[5]))
1084
                                &&((~spif_data[6])&&(~spif_data[5])))
1085
                                state <= `WBQSPI_CLEAR_STATUS;
1086
                        else
1087
                                state <= `WBQSPI_WAIT_TIL_IDLE;
1088
                end
1089
        end else if (state == `WBQSPI_ERASE_CMD)
1090
        begin // Know that WIP is clear on entry, WEN has just been commanded
1091
                spi_wr     <= 1'b0;
1092
                o_wb_ack   <= 1'b0;
1093
                o_wb_stall <= 1'b1;
1094
                spi_hold   <= 1'b0;
1095
                spi_spd <= 1'b0;
1096
                spi_dir <= 1'b0;
1097
                spif_req <= (spif_req) && (i_wb_cyc);
1098
 
1099
                // Here's the erase command
1100
                spi_in <= { 8'hd8, 2'h0, spif_data[19:14], 14'h000, 2'b00 };
1101
                spi_len <= 2'b11; // 32 bit write
1102
                // together with setting our copy of the WIP bit
1103
                write_in_progress <= 1'b1;
1104
                // keeping track of which sector we just erased
1105 7 dgisselq
                erased_sector <= spif_data[(ADDRESS_WIDTH-3):14];
1106 2 dgisselq
                // and marking this erase sector as no longer dirty
1107
                dirty_sector <= 1'b0;
1108
 
1109
                // Wait for a full stop before issuing this command
1110
                if ((~spi_busy)&&(~spi_wr)&&(o_qspi_cs_n))
1111
                begin // When our command is accepted, move to the next state
1112
                        spi_wr <= 1'b1;
1113
                        state <= `WBQSPI_ERASE_BLOCK;
1114
                end
1115
        end else if (state == `WBQSPI_ERASE_BLOCK)
1116
        begin
1117
                spi_wr     <= 1'b0;
1118
                spi_hold   <= 1'b0;
1119
                o_wb_stall <= 1'b1;
1120
                o_wb_ack   <= 1'b0;
1121
                spif_req <= (spif_req) && (i_wb_cyc);
1122
                // When the port clears, we can head back to idle
1123
                if ((~spi_busy)&&(~spi_wr))
1124
                begin
1125
                        o_wb_ack <= spif_req;
1126
                        state <= `WBQSPI_IDLE;
1127
                end
1128
        end else if (state == `WBQSPI_CLEAR_STATUS)
1129
        begin // Issue a clear status command
1130
                spi_wr <= 1'b1;
1131
                spi_hold <= 1'b0;
1132
                spi_len <= 2'b00; // 8 bit command
1133
                spi_in <= { 8'h30, 24'h00 };
1134
                spi_spd <= 1'b0;
1135
                spi_dir <= 1'b0;
1136
                last_status[6:5] <= 2'b00;
1137
                spif_req <= (spif_req) && (i_wb_cyc);
1138
                if ((spi_wr)&&(~spi_busy))
1139
                        state <= `WBQSPI_WAIT_TIL_IDLE;
1140
        end else if (state == `WBQSPI_IDLE_CHECK_WIP)
1141
        begin // We are now in read status register mode
1142
 
1143
                // No bus commands have (yet) been given
1144
                o_wb_stall <= 1'b1;
1145
                o_wb_ack   <= 1'b0;
1146
                spif_req <= (spif_req) && (i_wb_cyc);
1147
 
1148
                // Stay in this mode unless/until we get a command, or
1149
                //      the write is over
1150
                spi_wr <= (((~i_wb_cyc)||((~i_wb_data_stb)&&(~i_wb_ctrl_stb)))
1151
                                &&(write_in_progress));
1152
                spi_len <= 2'b00; // 8 bit reads
1153
                spi_spd <= 1'b0;  // SPI, not quad
1154
                spi_dir <= 1'b1;  // Read
1155
                if (spi_valid)
1156
                begin
1157
                        write_in_progress <= spi_out[0];
1158
                        if ((~spi_out[0])&&(write_in_progress))
1159
                                o_interrupt <= 1'b1;
1160
                end else
1161
                        o_interrupt <= 1'b0;
1162
 
1163
                if ((~spi_wr)&&(~spi_busy)&&(o_qspi_cs_n))
1164
                begin // We can now go to idle and process a command
1165
                        o_wb_stall <= 1'b0;
1166
                        o_wb_ack   <= 1'b0;
1167
                        state <= `WBQSPI_IDLE;
1168
                end
1169 7 dgisselq
`endif //       !READ_ONLY
1170 2 dgisselq
        end else // if (state == `WBQSPI_WAIT_TIL_IDLE) or anything else
1171
        begin
1172
                spi_wr     <= 1'b0;
1173
                spi_hold   <= 1'b0;
1174
                o_wb_stall <= 1'b1;
1175
                o_wb_ack   <= 1'b0;
1176
                spif_req   <= 1'b0;
1177
                if ((~spi_busy)&&(o_qspi_cs_n)&&(~spi_wr)) // Wait for a full
1178
                begin // clearing of the SPI port before moving on
1179
                        state <= `WBQSPI_IDLE;
1180
                        o_wb_stall <= 1'b0;
1181
                        o_wb_ack   <= 1'b0; // Shouldn't be acking anything here
1182
                end
1183
        end
1184 4 dgisselq
        end
1185 2 dgisselq
 
1186 4 dgisselq
        // Command and control during the reset sequence
1187
        assign  o_qspi_cs_n = (spif_override)?spif_cmd :w_qspi_cs_n;
1188
        assign  o_qspi_sck  = (spif_override)?spif_ctrl:w_qspi_sck;
1189
        assign  o_qspi_mod  = (spif_override)?   2'b01 :w_qspi_mod;
1190
        assign  o_qspi_dat  = (spif_override)?   4'b00 :w_qspi_dat;
1191 2 dgisselq
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.