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

Subversion Repositories qspiflash

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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