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

Subversion Repositories cfi_ctrl

[/] [cfi_ctrl/] [trunk/] [rtl/] [verilog/] [cfi_ctrl_engine.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 julius
////////////////////////////////////////////////////////////////// ////
2
////                                                              //// 
3
////  Common Flash Interface (CFI) controller                     //// 
4
////                                                              //// 
5
////  This file is part of the cfi_ctrl project                   //// 
6
////  http://opencores.org/project,cfi_ctrl                       //// 
7
////                                                              //// 
8
////  Description                                                 //// 
9
////  See below                                                   //// 
10
////                                                              //// 
11
////  To Do:                                                      //// 
12
////   -                                                          //// 
13
////                                                              //// 
14
////  Author(s):                                                  //// 
15
////      - Julius Baxter, julius@opencores.org                   //// 
16
////                                                              //// 
17
////////////////////////////////////////////////////////////////////// 
18
////                                                              //// 
19
//// Copyright (C) 2011 Authors and OPENCORES.ORG                 //// 
20
////                                                              //// 
21
//// This source file may be used and distributed without         //// 
22
//// restriction provided that this copyright statement is not    //// 
23
//// removed from the file and that any derivative work contains  //// 
24
//// the original copyright notice and the associated disclaimer. //// 
25
////                                                              //// 
26
//// This source file is free software; you can redistribute it   //// 
27
//// and/or modify it under the terms of the GNU Lesser General   //// 
28
//// Public License as published by the Free Software Foundation; //// 
29
//// either version 2.1 of the License, or (at your option) any   //// 
30
//// later version.                                               //// 
31
////                                                              //// 
32
//// This source is distributed in the hope that it will be       //// 
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   //// 
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //// 
35
//// PURPOSE.  See the GNU Lesser General Public License for more //// 
36
//// details.                                                     //// 
37
////                                                              //// 
38
//// You should have received a copy of the GNU Lesser General    //// 
39
//// Public License along with this source; if not, download it   //// 
40
//// from http://www.gnu.org/copyleft/lesser.html                 //// 
41
////                                                              ////
42
////////////////////////////////////////////////////////////////////// 
43
/*
44
 CFI controller engine.
45
 
46
 Contains main state machine and bus controls.
47
 
48
 Controlled via a simple interface to a bus controller interface.
49
 
50
 For now just implements an asynchronous controller.
51
 
52
 do_rst_i - reset the flash device
53
 do_init_i - initialise the device (write "read configuration register")
54
 do_readstatus_i - read the status of the device
55
 do_eraseblock_i - erase a block
56
 do_write_i - write a word an address
57
 do_read_i - read a word from an address
58
 
59
 bus_dat_o - data out to bus controller
60
 bus_dat_i - data in from bus controller
61
 bus_req_done_o - bus request done
62
 
63
 */
64
 
65
 
66
module cfi_ctrl_engine
67
  (
68
 
69
   clk_i, rst_i,
70
 
71
   do_rst_i,
72
   do_init_i,
73
   do_readstatus_i,
74
   do_clearstatus_i,
75
   do_eraseblock_i,
76
   do_unlockblock_i,
77
   do_write_i,
78
   do_read_i,
79
   do_readdeviceident_i,
80
   do_cfiquery_i,
81
 
82
   bus_dat_o,
83
   bus_dat_i,
84
   bus_adr_i,
85
   bus_req_done_o,
86
   bus_busy_o,
87
 
88
   flash_dq_io,
89
   flash_adr_o,
90
   flash_adv_n_o,
91
   flash_ce_n_o,
92
   flash_clk_o,
93
   flash_oe_n_o,
94
   flash_rst_n_o,
95
   flash_wait_i,
96
   flash_we_n_o,
97
   flash_wp_n_o
98
 
99
   );
100
 
101
   parameter flash_dq_width = 16;
102
   parameter flash_adr_width = 24;
103
 
104
   input clk_i, rst_i;
105
   input do_rst_i,
106
         do_init_i,
107
         do_readstatus_i,
108
         do_clearstatus_i,
109
         do_eraseblock_i,
110
         do_unlockblock_i,
111
         do_write_i,
112
         do_read_i,
113
         do_readdeviceident_i,
114
         do_cfiquery_i;
115
 
116
   output reg [flash_dq_width-1:0] bus_dat_o;
117
   input [flash_dq_width-1:0]       bus_dat_i;
118
   input [flash_adr_width-1:0]      bus_adr_i;
119
   output                          bus_req_done_o;
120
   output                          bus_busy_o;
121
 
122
 
123
   inout [flash_dq_width-1:0]       flash_dq_io;
124
   output [flash_adr_width-1:0]    flash_adr_o;
125
 
126
   output                          flash_adv_n_o;
127
   output                          flash_ce_n_o;
128
   output                          flash_clk_o;
129
   output                          flash_oe_n_o;
130
   output                          flash_rst_n_o;
131
   input                           flash_wait_i;
132
   output                          flash_we_n_o;
133
   output                          flash_wp_n_o;
134
 
135
   wire                            clk, rst;
136
 
137
assign clk = clk_i;
138
assign rst = rst_i;
139
 
140
   reg [5:0]                     bus_control_state;
141
 
142
   reg [flash_dq_width-1:0]      flash_cmd_to_write;
143
 
144
   /* regs for flash bus control signals */
145
   reg flash_adv_n_r;
146
   reg flash_ce_n_r;
147
   reg flash_oe_n_r;
148
   reg flash_we_n_r;
149
   reg flash_wp_n_r;
150
   reg flash_rst_n_r;
151
   reg [flash_dq_width-1:0]  flash_dq_o_r;
152
   reg [flash_adr_width-1:0] flash_adr_r;
153
 
154
   reg [3:0]                  flash_phy_state;
155
   reg [3:0]                  flash_phy_ctr;
156
   wire                      flash_phy_async_wait;
157
 
158
`define CFI_PHY_FSM_IDLE        0
159
`define CFI_PHY_FSM_WRITE_GO    1
160
`define CFI_PHY_FSM_WRITE_WAIT  2
161
`define CFI_PHY_FSM_WRITE_DONE  3
162
`define CFI_PHY_FSM_READ_GO     4
163
`define CFI_PHY_FSM_READ_WAIT   5
164
`define CFI_PHY_FSM_READ_DONE   6
165
`define CFI_PHY_FSM_RESET_GO    7
166
`define CFI_PHY_FSM_RESET_WAIT  8
167
`define CFI_PHY_FSM_RESET_DONE  9
168
 
169
   /* Defines according to CFI spec */
170
`define CFI_CMD_DAT_READ_STATUS_REG      8'h70
171
`define CFI_CMD_DAT_CLEAR_STATUS_REG     8'h50
172
`define CFI_CMD_DAT_WORD_PROGRAM         8'h40
173
`define CFI_CMD_DAT_BLOCK_ERASE          8'h20
174
`define CFI_CMD_DAT_READ_ARRAY           8'hff
175
`define CFI_CMD_DAT_WRITE_RCR            8'h60
176
`define CFI_CMD_DAT_CONFIRM_WRITE_RCR    8'h03
177
`define CFI_CMD_DAT_UNLOCKBLOCKSETUP     8'h60
178
`define CFI_CMD_DAT_CONFIRM_CMD          8'hd0
179
`define CFI_CMD_DAT_READDEVICEIDENT      8'h90
180
`define CFI_CMD_DAT_CFIQUERY             8'h98
181
 
182
 
183
   /* Main bus-controlled FSM states */
184
`define CFI_FSM_IDLE                   0
185
`define CFI_FSM_DO_WRITE               1
186
`define CFI_FSM_DO_WRITE_WAIT          2
187
`define CFI_FSM_DO_READ                3
188
`define CFI_FSM_DO_READ_WAIT           4
189
`define CFI_FSM_DO_BUS_ACK             5
190
`define CFI_FSM_DO_RESET               6
191
`define CFI_FSM_DO_RESET_WAIT          7
192
 
193
   /* Used to internally track what read more we're in
194
    2'b00 : read array mode
195
    2'b01 : read status mode
196
    else : something else*/
197
   reg [1:0]                             flash_device_read_mode;
198
 
199
   /* Track what read mode we're in */
200
   always @(posedge clk)
201
     if (rst)
202
       flash_device_read_mode <= 2'b00;
203
     else if (!flash_rst_n_o)
204
        flash_device_read_mode      <= 2'b00;
205
     else if (flash_phy_state == `CFI_PHY_FSM_WRITE_DONE) begin
206
        if (flash_cmd_to_write == `CFI_CMD_DAT_READ_ARRAY)
207
           flash_device_read_mode <= 2'b00;
208
        else if (flash_cmd_to_write == `CFI_CMD_DAT_READ_STATUS_REG)
209
           flash_device_read_mode <= 2'b01;
210
        else
211
           /* Some other mode */
212
           flash_device_read_mode <= 2'b11;
213
     end
214
 
215
   /* Main control state machine, controlled by the bus */
216
   always @(posedge clk)
217
     if (rst) begin
218
       /* Power up and start an asynchronous write to the "read config reg" */
219
        bus_control_state <= `CFI_FSM_IDLE;
220
        flash_cmd_to_write <= 0;
221
     end
222
     else
223
       case (bus_control_state)
224
         `CFI_FSM_IDLE : begin
225
            if (do_readstatus_i) begin
226
//             if (flash_device_read_mode != 2'b01) begin
227
                  flash_cmd_to_write <= `CFI_CMD_DAT_READ_STATUS_REG;
228
                  bus_control_state <= `CFI_FSM_DO_WRITE;
229
//             end
230
//             else begin
231
//                flash_cmd_to_write <= 0;
232
//                bus_control_state <= `CFI_FSM_DO_READ;
233
//             end
234
            end
235
            if (do_clearstatus_i) begin
236
               flash_cmd_to_write <= `CFI_CMD_DAT_CLEAR_STATUS_REG;
237
               bus_control_state <= `CFI_FSM_DO_WRITE;
238
            end
239
            if (do_eraseblock_i) begin
240
               flash_cmd_to_write <= `CFI_CMD_DAT_BLOCK_ERASE;
241
               bus_control_state <= `CFI_FSM_DO_WRITE;
242
            end
243
            if (do_write_i) begin
244
               flash_cmd_to_write <= `CFI_CMD_DAT_WORD_PROGRAM;
245
               bus_control_state <= `CFI_FSM_DO_WRITE;
246
            end
247
            if (do_read_i) begin
248
               if (flash_device_read_mode != 2'b00) begin
249
                  flash_cmd_to_write <= `CFI_CMD_DAT_READ_ARRAY;
250
                  bus_control_state <= `CFI_FSM_DO_WRITE;
251
               end
252
               else begin
253
                  flash_cmd_to_write <= 0;
254
                  bus_control_state <= `CFI_FSM_DO_READ;
255
               end
256
            end
257
            if (do_unlockblock_i) begin
258
               flash_cmd_to_write <= `CFI_CMD_DAT_UNLOCKBLOCKSETUP;
259
               bus_control_state <= `CFI_FSM_DO_WRITE;
260
            end
261
            if (do_rst_i) begin
262
               flash_cmd_to_write <= 0;
263
               bus_control_state <= `CFI_FSM_DO_RESET;
264
            end
265
            if (do_readdeviceident_i) begin
266
               flash_cmd_to_write <= `CFI_CMD_DAT_READDEVICEIDENT;
267
               bus_control_state <= `CFI_FSM_DO_WRITE;
268
            end
269
            if (do_cfiquery_i) begin
270
               flash_cmd_to_write <= `CFI_CMD_DAT_CFIQUERY;
271
               bus_control_state <= `CFI_FSM_DO_WRITE;
272
            end
273
 
274
         end // case: `CFI_FSM_IDLE
275
         `CFI_FSM_DO_WRITE : begin
276
            bus_control_state <= `CFI_FSM_DO_WRITE_WAIT;
277
         end
278
         `CFI_FSM_DO_WRITE_WAIT : begin
279
            /* Wait for phy controller to finish the write command */
280
            if (flash_phy_state==`CFI_PHY_FSM_WRITE_DONE) begin
281
               if (flash_cmd_to_write == `CFI_CMD_DAT_READ_STATUS_REG ||
282
                   flash_cmd_to_write == `CFI_CMD_DAT_READ_ARRAY ||
283
                   flash_cmd_to_write == `CFI_CMD_DAT_READDEVICEIDENT ||
284
                   flash_cmd_to_write == `CFI_CMD_DAT_CFIQUERY) begin
285
                  /* we just changed the read mode, so go ahead and do the
286
                   read */
287
                  bus_control_state <= `CFI_FSM_DO_READ;
288
               end
289
               else if (flash_cmd_to_write == `CFI_CMD_DAT_WORD_PROGRAM) begin
290
                  /* Setting up to do a word write, go to write again */
291
                  /* clear the command, to use the incoming data from the bus */
292
                  flash_cmd_to_write <= 0;
293
                  bus_control_state <= `CFI_FSM_DO_WRITE;
294
               end
295
               else if (flash_cmd_to_write == `CFI_CMD_DAT_BLOCK_ERASE ||
296
                        flash_cmd_to_write == `CFI_CMD_DAT_UNLOCKBLOCKSETUP)
297
               begin
298
                  /* first stage of a two-stage command requiring confirm */
299
                  bus_control_state <= `CFI_FSM_DO_WRITE;
300
                  flash_cmd_to_write <= `CFI_CMD_DAT_CONFIRM_CMD;
301
               end
302
               else
303
                  /* All other operations should see us acking the bus */
304
                  bus_control_state <= `CFI_FSM_DO_BUS_ACK;
305
            end
306
         end // case: `CFI_FSM_DO_WRITE_WAIT
307
          `CFI_FSM_DO_READ : begin
308
             bus_control_state <= `CFI_FSM_DO_READ_WAIT;
309
          end
310
          `CFI_FSM_DO_READ_WAIT : begin
311
             if (flash_phy_state==`CFI_PHY_FSM_READ_DONE) begin
312
                bus_control_state <= `CFI_FSM_DO_BUS_ACK;
313
             end
314
          end
315
          `CFI_FSM_DO_BUS_ACK :
316
             bus_control_state <= `CFI_FSM_IDLE;
317
         `CFI_FSM_DO_RESET :
318
           bus_control_state <= `CFI_FSM_DO_RESET_WAIT;
319
         `CFI_FSM_DO_RESET_WAIT : begin
320
            if (flash_phy_state==`CFI_PHY_FSM_RESET_DONE)
321
              bus_control_state <= `CFI_FSM_IDLE;
322
         end
323
          default :
324
             bus_control_state <= `CFI_FSM_IDLE;
325
       endcase // case (bus_control_state)
326
 
327
/* Tell the bus we're done */
328
assign bus_req_done_o = (bus_control_state==`CFI_FSM_DO_BUS_ACK);
329
assign bus_busy_o = !(bus_control_state == `CFI_FSM_IDLE);
330
 
331
/* Sample flash data for the system bus interface */
332
always @(posedge clk)
333
   if (rst)
334
      bus_dat_o <= 0;
335
   else if ((flash_phy_state == `CFI_PHY_FSM_READ_WAIT) &&
336
            /* Wait for t_vlqv */
337
            (!flash_phy_async_wait))
338
      /* Sample flash data */
339
      bus_dat_o <= flash_dq_io;
340
 
341
/* Flash physical interface control state machine */
342
always @(posedge clk)
343
   if (rst)
344
   begin
345
      flash_adv_n_r <= 1'b0;
346
      flash_ce_n_r  <= 1'b1;
347
      flash_oe_n_r  <= 1'b1;
348
      flash_we_n_r  <= 1'b1;
349
      flash_dq_o_r  <= 0;
350
      flash_adr_r   <= 0;
351
      flash_rst_n_r <= 0;
352
 
353
      flash_phy_state <= `CFI_PHY_FSM_IDLE;
354
   end
355
   else
356
   begin
357
      case (flash_phy_state)
358
         `CFI_PHY_FSM_IDLE : begin
359
            flash_rst_n_r <= 1'b1;
360
            flash_ce_n_r <= 1'b0;
361
 
362
            /* Take address from the bus controller */
363
            flash_adr_r  <= bus_adr_i;
364
 
365
            /* Wait for a read or write command */
366
            if (bus_control_state == `CFI_FSM_DO_WRITE)
367
            begin
368
               flash_phy_state <= `CFI_PHY_FSM_WRITE_GO;
369
               /* Are we going to write a command? */
370
               if (flash_cmd_to_write) begin
371
                  flash_dq_o_r <= {{(flash_dq_width-8){1'b0}},
372
                                   flash_cmd_to_write};
373
               end
374
               else
375
                  flash_dq_o_r <= bus_dat_i;
376
 
377
            end
378
            if (bus_control_state == `CFI_FSM_DO_READ) begin
379
               flash_phy_state <= `CFI_PHY_FSM_READ_GO;
380
            end
381
            if (bus_control_state == `CFI_FSM_DO_RESET) begin
382
               flash_phy_state <= `CFI_PHY_FSM_RESET_GO;
383
            end
384
         end
385
         `CFI_PHY_FSM_WRITE_GO: begin
386
            /* Assert CE, WE */
387
            flash_we_n_r <= 1'b0;
388
 
389
            flash_phy_state <= `CFI_PHY_FSM_WRITE_WAIT;
390
         end
391
         `CFI_PHY_FSM_WRITE_WAIT: begin
392
            /* Wait for t_wlwh */
393
            if (!flash_phy_async_wait) begin
394
               flash_phy_state <= `CFI_PHY_FSM_WRITE_DONE;
395
               flash_we_n_r <= 1'b1;
396
            end
397
         end
398
         `CFI_PHY_FSM_WRITE_DONE: begin
399
            flash_phy_state <= `CFI_PHY_FSM_IDLE;
400
         end
401
 
402
         `CFI_PHY_FSM_READ_GO: begin
403
            /* Assert CE, OE */
404
            /*flash_adv_n_r <= 1'b1;*/
405
            flash_ce_n_r <= 1'b0;
406
            flash_oe_n_r <= 1'b0;
407
            flash_phy_state <= `CFI_PHY_FSM_READ_WAIT;
408
         end
409
         `CFI_PHY_FSM_READ_WAIT: begin
410
            /* Wait for t_vlqv */
411
            if (!flash_phy_async_wait) begin
412
               flash_oe_n_r    <= 1'b1;
413
               flash_phy_state <= `CFI_PHY_FSM_READ_DONE;
414
            end
415
         end
416
         `CFI_PHY_FSM_READ_DONE: begin
417
            flash_phy_state <= `CFI_PHY_FSM_IDLE;
418
         end
419
        `CFI_PHY_FSM_RESET_GO: begin
420
           flash_phy_state <= `CFI_PHY_FSM_RESET_WAIT;
421
           flash_rst_n_r <= 1'b0;
422
           flash_oe_n_r <= 1'b1;
423
        end
424
        `CFI_PHY_FSM_RESET_WAIT : begin
425
           if (!flash_phy_async_wait) begin
426
              flash_rst_n_r    <= 1'b1;
427
              flash_phy_state <= `CFI_PHY_FSM_RESET_DONE;
428
           end
429
        end
430
        `CFI_PHY_FSM_RESET_DONE : begin
431
           flash_phy_state <= `CFI_PHY_FSM_IDLE;
432
        end
433
         default:
434
            flash_phy_state <= `CFI_PHY_FSM_IDLE;
435
      endcase
436
   end
437
 
438
/* Defaults are for 95ns access time part, 66MHz (15.15ns) system clock */
439
/* wlwh: cycles for WE assert to WE de-assert: write time */
440
parameter cfi_part_wlwh_cycles = 4; /* wlwh = 50ns, tck = 15ns, cycles = 4*/
441
/* elqv: cycles from adress  to data valid */
442
parameter cfi_part_elqv_cycles = 7; /* tsop 256mbit elqv = 95ns, tck = 15ns, cycles = 6*/
443
 
444
assign flash_phy_async_wait = (|flash_phy_ctr);
445
 
446
/* Load counter with wait times in cycles, determined by parameters. */
447
always @(posedge clk)
448
   if (rst)
449
      flash_phy_ctr <= 0;
450
   else if (flash_phy_state==`CFI_PHY_FSM_WRITE_GO)
451
      flash_phy_ctr <= cfi_part_wlwh_cycles - 1;
452
   else if (flash_phy_state==`CFI_PHY_FSM_READ_GO)
453
     flash_phy_ctr <= cfi_part_elqv_cycles - 2;
454
   else if (flash_phy_state==`CFI_PHY_FSM_RESET_GO)
455
     flash_phy_ctr <= 10;
456
   else if (|flash_phy_ctr)
457
      flash_phy_ctr <= flash_phy_ctr - 1;
458
 
459
   /* Signal to indicate when we should drive the data bus */
460
   wire flash_bus_write_enable;
461
   assign flash_bus_write_enable = (bus_control_state == `CFI_FSM_DO_WRITE) |
462
                                   (bus_control_state == `CFI_FSM_DO_WRITE_WAIT);
463
 
464
/* Assign signals to physical bus */
465
assign flash_dq_io = flash_bus_write_enable ? flash_dq_o_r :
466
                     {flash_dq_width{1'bz}};
467
assign flash_adr_o = flash_adr_r;
468
assign flash_adv_n_o = flash_adv_n_r;
469
assign flash_wp_n_o = 1'b1; /* Never write protect */
470
assign flash_ce_n_o = flash_ce_n_r;
471
assign flash_oe_n_o = flash_oe_n_r;
472
assign flash_we_n_o = flash_we_n_r;
473
assign flash_clk_o = 1'b1;
474
assign flash_rst_n_o = flash_rst_n_r;
475
endmodule // cfi_ctrl_engine
476
 
477
 
478
 
479
 

powered by: WebSVN 2.1.0

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