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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [bench/] [s25fl128p01m.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 xianfeng
//////////////////////////////////////////////////////////////////////////////
2
//  File name : s25fl128p01m.v
3
//////////////////////////////////////////////////////////////////////////////
4
//  Copyright (C) 2006-2007 Spansion, LLC.
5
//
6
//  MODIFICATION HISTORY :
7
//
8
//  version: |   author:      |  mod date: | changes made:
9
//    V1.0     S.Petrovic       06 Jul 05   Initial release
10
//    V1.1     S.Janevski       07 Jan 23   Extended device identification
11
//                                          Enable WRSR,SE,BE,DP in parallel
12
//                                          mode
13
//                                          In DP mode only RES is accepted
14
//                                          Implemented tpd time in DP mode
15
//////////////////////////////////////////////////////////////////////////////
16
//  PART DESCRIPTION:
17
//
18
//  Library:        FLASH
19
//  Technology:     FLASH MEMORY
20
//  Part:           S25FL128P01M
21
//
22
//  Description:128 Megabit Serial Flash Memory with 104 MHz SPI Bus Interface
23
//  Comments :
24
//      For correct simulation, simulator resolution should be set to 100 ps
25
//
26
//////////////////////////////////////////////////////////////////////////////
27
//  Known Bugs:
28
//
29
//////////////////////////////////////////////////////////////////////////////
30
 
31
//////////////////////////////////////////////////////////////////////////////
32
// MODULE DECLARATION                                                       //
33
//////////////////////////////////////////////////////////////////////////////
34
`timescale 1 ns/100 ps
35
module s25fl128p01m
36
(
37
    SCK      ,
38
    SI       ,
39
 
40
    PO7      ,
41
    PO6      ,
42
    PO5      ,
43
    PO4      ,
44
    PO3      ,
45
    PO2      ,
46
    PO1      ,
47
    PO0      ,
48
 
49
    CSNeg    ,
50
    HOLDNeg  ,
51
    WPNeg
52
);
53
 
54
////////////////////////////////////////////////////////////////////////
55
// Port / Part Pin Declarations
56
////////////////////////////////////////////////////////////////////////
57
    input  SCK     ;
58
    input  SI      ;
59
 
60
    inout  PO7     ;
61
    inout  PO6     ;
62
    inout  PO5     ;
63
    inout  PO4     ;
64
    inout  PO3     ;
65
    inout  PO2     ;
66
    inout  PO1     ;
67
    inout  PO0     ;
68
 
69
    input  CSNeg   ;
70
    input  HOLDNeg ;
71
    input  WPNeg    ;
72
 
73
// interconnect path delay signals
74
    wire  SCK_ipd      ;
75
    wire  SI_ipd       ;
76
 
77
    wire  PO7_ipd      ;
78
    wire  PO6_ipd      ;
79
    wire  PO5_ipd      ;
80
    wire  PO4_ipd      ;
81
    wire  PO3_ipd      ;
82
    wire  PO2_ipd      ;
83
    wire  PO1_ipd      ;
84
    wire  PO0_ipd      ;
85
 
86
    wire [7 : 0 ] PIn;
87
    assign PIn = {PO7_ipd,
88
                  PO6_ipd,
89
                  PO5_ipd,
90
                  PO4_ipd,
91
                  PO3_ipd,
92
                  PO2_ipd,
93
                  PO1_ipd,
94
                  PO0_ipd};
95
 
96
    wire [7 : 0 ] POut;
97
    assign POut = {PO7,
98
                   PO6,
99
                   PO5,
100
                   PO4,
101
                   PO3,
102
                   PO2,
103
                   PO1,
104
                   PO0};
105
 
106
    wire  CSNeg_ipd    ;
107
    wire  HOLDNeg_ipd  ;
108
    wire  WPNeg_ipd     ;
109
 
110
//  internal delays
111
    reg PP_in       ;
112
    reg PP_out      ;
113
    reg BE_in       ;
114
    reg BE_out      ;
115
    reg SE_in       ;
116
    reg SE_out      ;
117
    reg WR_in       ;
118
    reg WR_out      ;
119
    reg DP_in       ;
120
    reg DP_out      ;
121
    reg RES_in      ;
122
    reg RES_out     ;
123
 
124
    wire  PO7_z     ;
125
    wire  PO6_z     ;
126
    wire  PO5_z     ;
127
    wire  PO4_z     ;
128
    wire  PO3_z     ;
129
    wire  PO2_z     ;
130
    wire  PO1_z     ;
131
    wire  PO0_z     ;
132
 
133
    reg [15 : 0] POut_zd = 8'bZZZZZZZZ;
134
    reg [15 : 0] POut_z  = 8'bZZZZZZZZ;
135
 
136
    assign {PO7_z,
137
            PO6_z,
138
            PO5_z,
139
            PO4_z,
140
            PO3_z,
141
            PO2_z,
142
            PO1_z,
143
            PO0_z} = POut_z;
144
 
145
    parameter UserPreload     = 1;
146
    parameter mem_file_name   = "none";//"s25fl128p01m.mem";
147
 
148
    parameter TimingModel = "DefaultTimingModel";
149
 
150
    parameter PartID = "s25fl128p01m";
151
    parameter MaxData = 255;
152
    parameter SecSize = 262143;
153
    parameter SecNum  = 63;
154
    parameter HiAddrBit = 23;
155
    parameter AddrRANGE = 24'hFFFFFF;
156
    parameter BYTE = 8;
157
    parameter Manuf_ID = 8'h01;
158
    parameter ES = 8'h17;
159
    parameter Jedec_ID =8'h20; // first byte of Device ID
160
    parameter DeviceID = 24'h012018;
161
    parameter ExtendedID    = 16'h0300;
162
 
163
    // If speed simulation is needed uncomment following line
164
 
165
    //`define SPEEDSIM;
166
 
167
    // powerup
168
    reg PoweredUp;
169
 
170
    reg PDONE    ; ////Prog. Done
171
    reg PSTART   ; ////Start Programming
172
 
173
    reg EDONE    ; ////Era. Done
174
    reg ESTART   ; ////Start Erasing
175
 
176
    reg WDONE    ; //// Writing Done
177
    reg WSTART   ; ////Start writing
178
 
179
    //Command Register
180
    reg write;
181
    reg read_out;
182
 
183
    //Status reg.
184
    reg[7:0] Status_reg = 8'b0;
185
    reg[7:0] Status_reg_in = 8'b0;
186
 
187
    integer SA      = 0;         // 0 TO SecNum+1
188
    integer Byte_number = 0;
189
 
190
    //Address
191
    integer Address = 0;         // 0 - AddrRANGE
192
    reg change_addr;
193
    reg  rd_fast;// = 1'b1;
194
    reg  rd_slow;
195
    wire fast_rd;
196
    wire rd;
197
 
198
    reg  PRL_ACT = 1'b0;
199
    reg  serial_mode;// = 1'b1;
200
    reg  prl_mode;
201
    wire serial;
202
    wire prl;
203
 
204
    //Sector Protection Status
205
    reg [SecNum:0] Sec_Prot = 64'b0; //= SecNum'b0;
206
 
207
    // timing check violation
208
    reg Viol = 1'b0;
209
 
210
    integer Mem[0:AddrRANGE];
211
 
212
    integer WByte[0:255];
213
 
214
    integer AddrLo;
215
    integer AddrHi;
216
 
217
    reg[7:0]  old_bit, new_bit;
218
    integer old_int, new_int;
219
    integer wr_cnt;
220
 
221
    integer read_cnt = 0;
222
    integer prl_read_cnt = 0;
223
    integer read_addr = 0;
224
    reg[7:0] data_out;
225
    reg[39:0] ident_out;
226
 
227
    reg oe = 1'b0;
228
    event oe_event;
229
 
230
///////////////////////////////////////////////////////////////////////////////
231
//Interconnect Path Delay Section
232
///////////////////////////////////////////////////////////////////////////////
233
 
234
 buf   (SCK_ipd, SCK);
235
 buf   (SI_ipd, SI);
236
 
237
 buf   (PO7_ipd, PO7);
238
 buf   (PO6_ipd, PO6);
239
 buf   (PO5_ipd, PO5);
240
 buf   (PO4_ipd, PO4);
241
 buf   (PO3_ipd, PO3);
242
 buf   (PO2_ipd, PO2);
243
 buf   (PO1_ipd, PO1);
244
 buf   (PO0_ipd, PO0);
245
 
246
 buf   (CSNeg_ipd, CSNeg);
247
 buf   (HOLDNeg_ipd, HOLDNeg);
248
 buf   (WPNeg_ipd, WPNeg);
249
 
250
///////////////////////////////////////////////////////////////////////////////
251
// Propagation  delay Section
252
///////////////////////////////////////////////////////////////////////////////
253
    nmos   (PO7,   PO7_z , 1);
254
    nmos   (PO6,   PO6_z , 1);
255
    nmos   (PO5,   PO5_z , 1);
256
    nmos   (PO4,   PO4_z , 1);
257
    nmos   (PO3,   PO3_z , 1);
258
    nmos   (PO2,   PO2_z , 1);
259
    nmos   (PO1,   PO1_z , 1);
260
    nmos   (PO0,   PO0_z , 1);
261
 
262
    wire deg;
263
    //VHDL VITAL CheckEnable equivalents
264
    wire prl_wr;
265
    assign prl_wr = prl && deg;
266
    wire prl_rd;
267
    assign prl_rd = prl && rd;
268
    wire serial_rd;
269
    assign serial_rd = serial && rd;
270
    wire prl_fast_rd;
271
    assign prl_fast_rd = prl && fast_rd;
272
    wire serial_fast_rd;
273
    assign serial_fast_rd = serial && fast_rd;
274
    wire power;
275
    assign power = PoweredUp;
276
 
277
 specify
278
        // tipd delays: interconnect path delays , mapped to input port delays.
279
        // In Verilog is not necessary to declare any tipd_ delay variables,
280
        // they can be taken from SDF file
281
        // With all the other delays real delays would be taken from SDF file
282
 
283
                        // tpd delays
284
     specparam           tpd_SCK_PO7              =1;
285
     specparam           tpd_SCK_PO0              =1;
286
     specparam           tpd_CSNeg_PO7            =1;
287
     specparam           tpd_CSNeg_PO0            =1;
288
     specparam           tpd_HOLDNeg_PO7          =1;
289
     specparam           tpd_HOLDNeg_PO0          =1;
290
 
291
     specparam           tsetup_SI_SCK           =1;   //tsuDAT /
292
     specparam           tsetup_PO0_SCK          =1;   //tsuDAT /
293
     specparam           tsetup_CSNeg_SCK        =1;   // tCSS /
294
     specparam           tsetup_HOLDNeg_SCK      =1;   //tHD /
295
     specparam           tsetup_SCK_HOLDNeg      =1;   //tCH \
296
     specparam           tsetup_WPNeg_CSNeg       =1;   //tWPS \
297
 
298
                          // thold values: hold times
299
     specparam           thold_SI_SCK            =1; //thdDAT /
300
     specparam           thold_PO0_SCK            =1; //thdDAT /
301
     specparam           thold_CSNeg_SCK         =1; //tCSH /
302
     specparam           thold_HOLDNeg_SCK       =1; //tCD /
303
     specparam           thold_SCK_HOLDNeg       =1; //tHC \
304
     specparam           thold_WPNeg_CSNeg        =1; //tWPH \
305
 
306
        // tpw values: pulse width
307
     specparam           tpw_SCK_serial_posedge   =1; //tWH
308
     specparam           tpw_SCK_prl_posedge      =1; //tWH
309
     specparam           tpw_SCK_serial_negedge   =1; //tWL
310
     specparam           tpw_SCK_prl_negedge      =1; //tWL
311
     specparam           tpw_CSNeg_serial_posedge =1; //tCS
312
     specparam           tpw_CSNeg_prl_posedge    =1; //tCS
313
 
314
        // tperiod min (calculated as 1/max freq)
315
     specparam           tperiod_SCK_serial_rd       =1; // fSCK = 40MHz
316
     specparam           tperiod_SCK_prl_rd          =1; // fSCK = 6MHz
317
     specparam           tperiod_SCK_serial_fast_rd  =1; // fSCK = 104MHz
318
     specparam           tperiod_SCK_prl_fast_rd     =1; // fSCK = 10MHz
319
 
320
        // tdevice values: values for internal delays
321
        `ifdef SPEEDSIM
322
            // Page Program Operation
323
            specparam   tdevice_PP                     = 30000; //30 us;
324
                    //Sector Erase Operation
325
            specparam   tdevice_SE                     = 4e6; //4 ms;
326
                    //Bulk Erase Operation
327
            specparam   tdevice_BE                     = 256e6; //256 ms;
328
                    //Write Status Register Operation
329
            specparam   tdevice_WR                     = 1000000; // 1 ms;
330
                    //Software Protect Mode
331
            specparam   tdevice_DP                     = 3000; // 3 us;
332
                    //Release from Software Protect Mode
333
            specparam   tdevice_RES                    = 30000; // 30 us;
334
                    //VCC (min) to CS# Low
335
            specparam   tdevice_PU                     = 45000000; //45 ms;
336
        `else
337
            // Page Program Operation
338
            specparam   tdevice_PP                     = 3000000; //3 ms;
339
                    //Sector Erase Operation
340
            specparam   tdevice_SE                     = 4e9; //4 sec;
341
                    //Bulk Erase Operation
342
            specparam   tdevice_BE                     = 256e9; //256 sec;
343
                    //Write Status Register Operation
344
            specparam   tdevice_WR                     = 100000000; // 100 ms;
345
                    //Software Protect Mode
346
            specparam   tdevice_DP                     = 3000; // 3 us;
347
                    //Release from Software Protect Mode
348
            specparam   tdevice_RES                    = 30000; // 30 us;
349
                    //VCC (min) to CS# Low
350
            specparam   tdevice_PU                     = 45000000; //45 ms;
351
        `endif//SPEEDSIM
352
 
353
///////////////////////////////////////////////////////////////////////////////
354
// Input Port  Delays  don't require Verilog description
355
///////////////////////////////////////////////////////////////////////////////
356
// Path delays                                                               //
357
///////////////////////////////////////////////////////////////////////////////
358
  if (serial) (SCK => PO7) = tpd_SCK_PO7;
359
  if (serial && CSNeg )(CSNeg => PO7) = tpd_CSNeg_PO7;
360
  if (serial) (HOLDNeg => PO7) = tpd_HOLDNeg_PO7;
361
 
362
  if (prl) (SCK *> PO0) = tpd_SCK_PO0;
363
  if (prl) (SCK *> PO1) = tpd_SCK_PO0;
364
  if (prl) (SCK *> PO2) = tpd_SCK_PO0;
365
  if (prl) (SCK *> PO3) = tpd_SCK_PO0;
366
  if (prl) (SCK *> PO4) = tpd_SCK_PO0;
367
  if (prl) (SCK *> PO5) = tpd_SCK_PO0;
368
  if (prl) (SCK *> PO6) = tpd_SCK_PO0;
369
  if (prl) (SCK *> PO7) = tpd_SCK_PO0;
370
  if (prl && CSNeg )(CSNeg => PO0) = tpd_CSNeg_PO0;
371
  if (prl && CSNeg )(CSNeg => PO1) = tpd_CSNeg_PO0;
372
  if (prl && CSNeg )(CSNeg => PO2) = tpd_CSNeg_PO0;
373
  if (prl && CSNeg )(CSNeg => PO3) = tpd_CSNeg_PO0;
374
  if (prl && CSNeg )(CSNeg => PO4) = tpd_CSNeg_PO0;
375
  if (prl && CSNeg )(CSNeg => PO5) = tpd_CSNeg_PO0;
376
  if (prl && CSNeg )(CSNeg => PO6) = tpd_CSNeg_PO0;
377
  if (prl && CSNeg )(CSNeg => PO7) = tpd_CSNeg_PO0;
378
  if (prl)(HOLDNeg => PO0) = tpd_HOLDNeg_PO0;
379
  if (prl)(HOLDNeg => PO1) = tpd_HOLDNeg_PO0;
380
  if (prl)(HOLDNeg => PO2) = tpd_HOLDNeg_PO0;
381
  if (prl)(HOLDNeg => PO3) = tpd_HOLDNeg_PO0;
382
  if (prl)(HOLDNeg => PO4) = tpd_HOLDNeg_PO0;
383
  if (prl)(HOLDNeg => PO5) = tpd_HOLDNeg_PO0;
384
  if (prl)(HOLDNeg => PO6) = tpd_HOLDNeg_PO0;
385
  if (prl)(HOLDNeg => PO7) = tpd_HOLDNeg_PO0;
386
 
387
////////////////////////////////////////////////////////////////////////////////
388
// Timing Violation                                                           //
389
////////////////////////////////////////////////////////////////////////////////
390
        $setup ( WPNeg , negedge CSNeg, tsetup_WPNeg_CSNeg, Viol);
391
        $setup ( negedge HOLDNeg, posedge SCK, tsetup_HOLDNeg_SCK, Viol);
392
        $setup ( posedge SCK, posedge HOLDNeg, tsetup_SCK_HOLDNeg, Viol);
393
 
394
        $setup ( PO0 , posedge SCK &&& prl_wr , tsetup_PO0_SCK, Viol);
395
        $setup ( PO1 , posedge SCK &&& prl_wr , tsetup_PO0_SCK, Viol);
396
        $setup ( PO2 , posedge SCK &&& prl_wr , tsetup_PO0_SCK, Viol);
397
        $setup ( PO3 , posedge SCK &&& prl_wr , tsetup_PO0_SCK, Viol);
398
        $setup ( PO4 , posedge SCK &&& prl_wr , tsetup_PO0_SCK, Viol);
399
        $setup ( PO5 , posedge SCK &&& prl_wr , tsetup_PO0_SCK, Viol);
400
        $setup ( PO6 , posedge SCK &&& prl_wr , tsetup_PO0_SCK, Viol);
401
        $setup ( PO7 , posedge SCK &&& prl_wr , tsetup_PO0_SCK, Viol);
402
 
403
        $hold ( posedge CSNeg, WPNeg,  thold_WPNeg_CSNeg, Viol);
404
        $hold ( posedge SCK, negedge HOLDNeg, thold_HOLDNeg_SCK, Viol);
405
        $hold ( posedge HOLDNeg, posedge SCK, thold_SCK_HOLDNeg, Viol);
406
 
407
        $hold ( posedge SCK , PO0 &&& prl_wr, thold_PO0_SCK, Viol);
408
        $hold ( posedge SCK , PO1 &&& prl_wr, thold_PO0_SCK, Viol);
409
        $hold ( posedge SCK , PO2 &&& prl_wr, thold_PO0_SCK, Viol);
410
        $hold ( posedge SCK , PO3 &&& prl_wr, thold_PO0_SCK, Viol);
411
        $hold ( posedge SCK , PO4 &&& prl_wr, thold_PO0_SCK, Viol);
412
        $hold ( posedge SCK , PO5 &&& prl_wr, thold_PO0_SCK, Viol);
413
        $hold ( posedge SCK , PO6 &&& prl_wr, thold_PO0_SCK, Viol);
414
        $hold ( posedge SCK , PO7 &&& prl_wr, thold_PO0_SCK, Viol);
415
 
416
        $setuphold ( posedge SCK, SI &&& serial, tsetup_SI_SCK,
417
                                                  thold_SI_SCK, Viol);
418
        $setuphold ( posedge SCK, CSNeg &&& power, tsetup_CSNeg_SCK,
419
                                                    thold_CSNeg_SCK, Viol);
420
 
421
        $width (posedge SCK &&& serial, tpw_SCK_serial_posedge);
422
        $width (posedge SCK &&& prl, tpw_SCK_prl_posedge);
423
        $width (negedge SCK &&& serial, tpw_SCK_serial_negedge);
424
        $width (negedge SCK &&& prl, tpw_SCK_prl_negedge);
425
 
426
        $width (posedge CSNeg &&& serial, tpw_CSNeg_serial_posedge);
427
        $width (posedge CSNeg &&& prl, tpw_CSNeg_prl_posedge);
428
 
429
        $period (posedge SCK &&& serial_rd, tperiod_SCK_serial_rd);
430
        $period (posedge SCK &&& prl_rd, tperiod_SCK_prl_rd);
431
        $period (posedge SCK &&& serial_fast_rd, tperiod_SCK_serial_fast_rd);
432
        $period (posedge SCK &&& prl_fast_rd, tperiod_SCK_prl_fast_rd);
433
 
434
    endspecify
435
 
436
////////////////////////////////////////////////////////////////////////////////
437
// Main Behavior Block                                                        //
438
////////////////////////////////////////////////////////////////////////////////
439
// FSM states
440
 parameter IDLE            =4'd0;
441
 parameter WRITE_SR        =4'd1;
442
 parameter DP_DOWN_WAIT    =4'd2;
443
 parameter DP_DOWN         =4'd3;
444
 parameter SECTOR_ER       =4'd4;
445
 parameter BULK_ER         =4'd5;
446
 parameter PAGE_PG         =4'd6;
447
 
448
 reg [3:0] current_state;
449
 reg [3:0] next_state;
450
 
451
// Instructions
452
 parameter NONE            =5'd0;
453
 parameter WREN            =5'd1;
454
 parameter WRDI            =5'd2;
455
 parameter WRSR            =5'd3;
456
 parameter RDSR            =5'd4;
457
 parameter READ            =5'd5;
458
 parameter FAST_READ       =5'd6;
459
 parameter SE              =5'd7;
460
 parameter BE              =5'd8;
461
 parameter PP              =5'd9;
462
 parameter DP              =5'd10;
463
 parameter RDID            =5'd11;
464
 parameter RES_READ_ES     =5'd12;
465
 parameter READ_ID         =5'd13;
466
 parameter ENTER_PRL       =5'd14;
467
 parameter EXIT_PRL        =5'd15;
468
 
469
 reg [4:0] Instruct;
470
 
471
//Bus cycle states
472
 parameter STAND_BY        =3'd0;
473
 parameter CODE_BYTE       =3'd1;
474
 parameter ADDRESS_BYTES   =3'd2;
475
 parameter DUMMY_BYTES     =3'd3;
476
 parameter DATA_BYTES      =3'd4;
477
 
478
 reg [2:0] bus_cycle_state;
479
 
480
 reg deq;
481
    always @(PIn, POut)
482
    begin
483
      if (PIn==POut)
484
        deq=1'b1;
485
      else
486
        deq=1'b0;
487
    end
488
    // chech when data is generated from model to avoid setuphold check in
489
    // those occasion
490
    assign deg=deq;
491
 
492
    initial
493
    begin : Init
494
 
495
        write    = 1'b0;
496
        read_out  = 1'b0;
497
        Address   = 0;
498
        change_addr = 1'b0;
499
 
500
        PDONE    = 1'b1;
501
        PSTART   = 1'b0;
502
 
503
        EDONE    = 1'b1;
504
        ESTART   = 1'b0;
505
 
506
        WDONE    = 1'b1;
507
        WSTART   = 1'b0;
508
 
509
        DP_in = 1'b0;
510
        DP_out = 1'b0;
511
        RES_in = 1'b0;
512
        RES_out = 1'b0;
513
        Instruct = NONE;
514
        bus_cycle_state = STAND_BY;
515
        current_state = IDLE;
516
        next_state = IDLE;
517
    end
518
 
519
    // initialize memory
520
    initial
521
    begin: InitMemory
522
    integer i;
523
 
524
        for (i=0;i<=AddrRANGE;i=i+1)
525
        begin
526
            Mem[i] = MaxData;
527
        end
528
 
529
        if ((UserPreload) && !(mem_file_name == "none"))
530
        begin
531
           // Memory Preload
532
           //s25fl128p01m.mem, memory preload file
533
           //  @aaaaaa - <aaaaaa> stands for address
534
           //  dd      - <dd> is byte to be written at Mem(aaaaaa++)
535
           // (aaaaaa is incremented at every load)
536
           $readmemh(mem_file_name,Mem);
537
        end
538
    end
539
 
540
    //Power Up time;
541
    initial
542
    begin
543
        PoweredUp = 1'b0;
544
        #tdevice_PU PoweredUp = 1'b1;
545
    end
546
 
547
   always @(posedge DP_in)
548
   begin:TDPr
549
     #tdevice_DP DP_out = DP_in;
550
   end
551
   always @(negedge DP_in)
552
   begin:TDPf
553
     #1 DP_out = DP_in;
554
   end
555
 
556
   always @(posedge RES_in)
557
   begin:TRESr
558
     #tdevice_RES RES_out = RES_in;
559
   end
560
   always @(negedge RES_in)
561
   begin:TRESf
562
     #1 RES_out = RES_in;
563
   end
564
 
565
   always @(next_state or PoweredUp)
566
   begin: StateTransition
567
       if (PoweredUp)
568
       begin
569
           current_state = next_state;
570
       end
571
   end
572
 
573
   always @(PoweredUp)
574
   begin:CheckCEOnPowerUP
575
       if ((~PoweredUp) && (~CSNeg_ipd))
576
           $display ("Device is selected during Power Up");
577
   end
578
 
579
//   ///////////////////////////////////////////////////////////////////////////
580
//   // Instruction cycle decode
581
//   ///////////////////////////////////////////////////////////////////////////
582
 integer data_cnt = 0;
583
 integer addr_cnt = 0;
584
 integer code_cnt = 0;
585
 integer dummy_cnt = 0;
586
 integer bit_cnt = 0;
587
 reg[2047:0] Data_in = 2048'b0;
588
 integer prl_data_in [0:255];
589
 reg[7:0] code = 8'b0;
590
 reg[7:0] code_in = 8'b0;
591
 reg[7:0] Byte_slv = 8'b0;
592
 reg[HiAddrBit:0] addr_bytes;
593
 reg[23:0] Address_in = 8'b0;
594
 
595
 reg rising_edge_CSNeg_ipd  = 1'b0;
596
 reg falling_edge_CSNeg_ipd = 1'b0;
597
 reg rising_edge_SCK_ipd    = 1'b0;
598
 reg falling_edge_SCK_ipd   = 1'b0;
599
 
600
    always @(falling_edge_CSNeg_ipd or rising_edge_CSNeg_ipd
601
    or rising_edge_SCK_ipd or falling_edge_SCK_ipd)
602
    begin: Buscycle1
603
        integer i;
604
        integer j;
605
        if (falling_edge_CSNeg_ipd)
606
        begin
607
            if (bus_cycle_state==STAND_BY)
608
            begin
609
                bus_cycle_state = CODE_BYTE;
610
                Instruct = NONE;
611
                write = 1'b1;
612
                code_cnt = 0;
613
                addr_cnt = 0;
614
                data_cnt = 0;
615
                dummy_cnt = 0;
616
            end
617
        end
618
 
619
        if (rising_edge_SCK_ipd)
620
        begin
621
            if ( HOLDNeg_ipd)
622
            begin
623
                case (bus_cycle_state)
624
                    CODE_BYTE :
625
                    begin
626
                        serial_mode = 1'b1;
627
                        prl_mode = 1'b0;
628
                        code_in[code_cnt] = SI_ipd;
629
                        code_cnt = code_cnt + 1;
630
                        if (code_cnt == BYTE)
631
                        begin
632
                            for (i=0;i<=7;i=i+1)
633
                            begin
634
                                code[i] = code_in[7-i];
635
                            end
636
                            case(code)
637
                                8'b00000110 :
638
                                begin
639
                                    Instruct = WREN;
640
                                    bus_cycle_state = DATA_BYTES;
641
                                end
642
                                8'b00000100 :
643
                                begin
644
                                    Instruct = WRDI;
645
                                    bus_cycle_state = DATA_BYTES;
646
                                end
647
                                8'b00000001 :
648
                                begin
649
                                    Instruct = WRSR;
650
                                    bus_cycle_state = DATA_BYTES;
651
                                end
652
                                8'b00000101 :
653
                                begin
654
                                    Instruct = RDSR;
655
                                    bus_cycle_state = DATA_BYTES;
656
                                end
657
                                8'b00000011 :
658
                                begin
659
                                    Instruct = READ;
660
                                    bus_cycle_state = ADDRESS_BYTES;
661
                                end
662
                                8'b00001011 :
663
                                begin
664
                                    Instruct = FAST_READ;
665
                                    if (~PRL_ACT)
666
                                        bus_cycle_state = ADDRESS_BYTES;
667
                                end
668
                                8'b10101011 :
669
                                begin
670
                                    Instruct = RES_READ_ES;
671
                                    bus_cycle_state = DUMMY_BYTES;
672
                                end
673
                                8'b11011000 :
674
                                begin
675
                                    Instruct = SE;
676
                                    bus_cycle_state = ADDRESS_BYTES;
677
                                end
678
                                8'b11000111 :
679
                                begin
680
                                    Instruct = BE;
681
                                    bus_cycle_state = DATA_BYTES;
682
                                end
683
                                8'b00000010 :
684
                                begin
685
                                    Instruct = PP;
686
                                    bus_cycle_state = ADDRESS_BYTES;
687
                                end
688
                                8'b10111001 :
689
                                begin
690
                                    Instruct = DP;
691
                                    bus_cycle_state = DATA_BYTES;
692
                                end
693
                                8'b10011111 :
694
                                begin
695
                                    Instruct = RDID;
696
                                    bus_cycle_state = DATA_BYTES;
697
                                end
698
                                8'b10010000 :
699
                                begin
700
                                    Instruct = READ_ID;
701
                                    bus_cycle_state = ADDRESS_BYTES;
702
                                end
703
                                8'b01010101 :
704
                                begin
705
                                    Instruct = ENTER_PRL;
706
                                    bus_cycle_state = DATA_BYTES;
707
                                end
708
                                8'b01000101 :
709
                                begin
710
                                    Instruct = EXIT_PRL;
711
                                    bus_cycle_state = DATA_BYTES;
712
                                end
713
                            endcase
714
                        end
715
                    end
716
 
717
                    ADDRESS_BYTES :
718
                    begin
719
                        Address_in[addr_cnt] = SI_ipd;
720
                        addr_cnt = addr_cnt + 1;
721
                        if (addr_cnt == 3*BYTE)
722
                        begin
723
                            for (i=23;i>=23-HiAddrBit;i=i-1)
724
                            begin
725
                                addr_bytes[23-i] = Address_in[i];
726
                            end
727
                            Address = addr_bytes;
728
                            change_addr = 1'b1;
729
                            #1 change_addr = 1'b0;
730
                            if (Instruct == FAST_READ)
731
                                bus_cycle_state = DUMMY_BYTES;
732
                            else
733
                                bus_cycle_state = DATA_BYTES;
734
                        end
735
                    end
736
 
737
                    DUMMY_BYTES :
738
                    begin
739
                        dummy_cnt = dummy_cnt + 1;
740
                        if ((dummy_cnt == BYTE && Instruct == FAST_READ) ||
741
                            (dummy_cnt == 3*BYTE && Instruct == RES_READ_ES))
742
                            bus_cycle_state = DATA_BYTES;
743
                    end
744
 
745
                    DATA_BYTES :
746
                    begin
747
                        if (PRL_ACT)
748
                        begin
749
                            serial_mode = 1'b0;
750
                            prl_mode = 1'b1;
751
                        end
752
                        else
753
                        begin
754
                            serial_mode = 1'b1;
755
                            prl_mode = 1'b0;
756
                        end
757
                        if (serial_mode)
758
                        begin
759
                            if (data_cnt > 2047)
760
                            //In case of serial mode and PP, if more than 256
761
                            //bytes are sent to the device
762
                            begin
763
                                if (bit_cnt == 0)
764
                                begin
765
                                    for (i=0;i<=(255*BYTE-1);i=i+1)
766
                                    begin
767
                                        Data_in[i] = Data_in[i+8];
768
                                    end
769
                                end
770
                                Data_in[2040 + bit_cnt] = SI_ipd;
771
                                bit_cnt = bit_cnt + 1;
772
                                if (bit_cnt == 8)
773
                                begin
774
                                    bit_cnt = 0;
775
                                end
776
                                data_cnt = data_cnt + 1;
777
                            end
778
                            else
779
                            begin
780
                                Data_in[data_cnt] = SI_ipd;
781
                                data_cnt = data_cnt + 1;
782
                                bit_cnt = 0;
783
                            end
784
                        end
785
                        else
786
                        begin
787
                            if (data_cnt > 255)
788
                            //In case of parallel mode and PP, if more than 256
789
                            //bytes are sent to the device
790
                            begin
791
                                for (i=0;i<=254;i=i+1)
792
                                begin
793
                                    prl_data_in[i] = prl_data_in[i+1];
794
                                end
795
                                prl_data_in[255] = PIn;
796
                                data_cnt = data_cnt + 1;
797
                            end
798
                            else
799
                            begin
800
                                prl_data_in[data_cnt] = PIn;
801
                                data_cnt = data_cnt + 1;
802
                            end
803
                        end
804
                    end
805
                endcase
806
            end
807
        end
808
 
809
        if (falling_edge_SCK_ipd)
810
        begin
811
            if (bus_cycle_state==DATA_BYTES && (~CSNeg_ipd) && (HOLDNeg_ipd))
812
                if (Instruct == READ || Instruct == RES_READ_ES ||
813
                    Instruct == FAST_READ || Instruct == RDSR ||
814
                    Instruct == RDID || Instruct == READ_ID)
815
                begin
816
                    if (PRL_ACT)
817
                    begin
818
                        serial_mode = 1'b0;
819
                        prl_mode = 1'b1;
820
                    end
821
                    else
822
                    begin
823
                        serial_mode = 1'b1;
824
                        prl_mode = 1'b0;
825
                    end
826
                    read_out = 1'b1;
827
                    #1 read_out = 1'b0;
828
                end
829
        end
830
        if (rising_edge_CSNeg_ipd)
831
        begin
832
            if ((bus_cycle_state != DATA_BYTES) && (bus_cycle_state !=
833
                                                            DUMMY_BYTES))
834
                bus_cycle_state = STAND_BY;
835
            else
836
            begin
837
            if (bus_cycle_state == DATA_BYTES)
838
            begin
839
                bus_cycle_state = STAND_BY;
840
                if (HOLDNeg_ipd)
841
                begin
842
                    case (Instruct)
843
                        WREN,
844
                        WRDI,
845
                        DP,
846
                        BE,
847
                        SE :
848
                        begin
849
                            if (data_cnt == 0)
850
                                write = 1'b0;
851
                        end
852
 
853
                        ENTER_PRL,
854
                        EXIT_PRL :
855
                        begin
856
                            if (data_cnt == 0)
857
                            begin
858
                                write = 1'b0;
859
                                if (Instruct == ENTER_PRL)
860
                                    PRL_ACT = 1'b1;
861
                                else if (Instruct == EXIT_PRL)
862
                                    PRL_ACT = 1'b0;
863
                            end
864
                        end
865
 
866
                        RES_READ_ES:
867
                        begin
868
                            write = 1'b0;
869
                        end
870
 
871
                        WRSR :
872
                        begin
873
                            if (data_cnt == BYTE)
874
                                write = 1'b0;
875
                                if (PRL_ACT == 1'b0)
876
                                    Status_reg_in = Data_in[7:0];
877
                                else
878
                                    Status_reg_in = prl_data_in[0];
879
                        end
880
 
881
                        PP :
882
                        begin
883
                            if (data_cnt > 0)
884
                            begin
885
                                if (serial_mode)
886
                                begin
887
                                    if ((data_cnt % 8) == 0)
888
                                    begin
889
                                        write = 1'b0;
890
                                        for (i=0;i<=255;i=i+1)
891
                                        begin
892
                                            for (j=7;j>=0;j=j-1)
893
                                            begin
894
                                                Byte_slv[j] =
895
                                                Data_in[(i*8) + (7-j)];
896
                                            end
897
                                            WByte[i] = Byte_slv;
898
                                        end
899
                                        if (data_cnt > 256*BYTE)
900
                                            Byte_number = 255;
901
                                        else
902
                                            Byte_number = ((data_cnt/8) - 1);
903
                                    end
904
                                end
905
                                else
906
                                begin
907
                                    write = 1'b0;
908
                                    for (i=0;i<=255;i=i+1)
909
                                    begin
910
                                        WByte[i] = prl_data_in[i];
911
                                    end
912
                                    if (data_cnt > 256)
913
                                        Byte_number = 255;
914
                                    else
915
                                        Byte_number = (data_cnt - 1);
916
                                end
917
                            end
918
                        end
919
                    endcase
920
                end
921
            end
922
            else
923
                if (bus_cycle_state == DUMMY_BYTES)
924
                begin
925
                    bus_cycle_state = STAND_BY;
926
                    if (HOLDNeg_ipd && (Instruct == RES_READ_ES) &&
927
                    (dummy_cnt == 0))
928
                        write = 1'b0;
929
                end
930
            end
931
        end
932
    end
933
 
934
    assign serial = serial_mode;
935
    assign prl = prl_mode;
936
 
937
//    /////////////////////////////////////////////////////////////////////////
938
//    // Timing control for the Program Operations
939
//    // start
940
//    /////////////////////////////////////////////////////////////////////////
941
 
942
 event pdone_event;
943
 
944
    always @(PSTART)
945
    begin
946
        if (PSTART && PDONE)
947
        begin
948
            PDONE = 1'b0;
949
            ->pdone_event;
950
        end
951
    end
952
 
953
    always @(pdone_event)
954
    begin:pdone_process
955
        PDONE = 1'b0;
956
        #tdevice_PP PDONE = 1'b1;
957
    end
958
 
959
//    /////////////////////////////////////////////////////////////////////////
960
//    // Timing control for the Write Status Register Operation
961
//    // start
962
//    /////////////////////////////////////////////////////////////////////////
963
 
964
 event wdone_event;
965
 
966
    always @(WSTART)
967
    begin
968
        if (WSTART && WDONE)
969
        begin
970
            WDONE = 1'b0;
971
            ->wdone_event;
972
        end
973
    end
974
 
975
    always @(wdone_event)
976
    begin:wdone_process
977
        WDONE = 1'b0;
978
        #tdevice_WR WDONE = 1'b1;
979
    end
980
 
981
//    /////////////////////////////////////////////////////////////////////////
982
//    // Timing control for the Erase Operations
983
//    /////////////////////////////////////////////////////////////////////////
984
 time duration_erase;
985
 
986
    event edone_event;
987
 
988
    always @(ESTART)
989
    begin: erase
990
        if (ESTART && EDONE)
991
        begin
992
            if (Instruct == BE)
993
            begin
994
                duration_erase = tdevice_BE;
995
            end
996
            else //if (Instruct == SE)
997
            begin
998
                duration_erase = tdevice_SE;
999
            end
1000
 
1001
            EDONE = 1'b0;
1002
            ->edone_event;
1003
        end
1004
    end
1005
 
1006
    always @(edone_event)
1007
    begin : edone_process
1008
        EDONE = 1'b0;
1009
        #duration_erase EDONE = 1'b1;
1010
    end
1011
 
1012
//    /////////////////////////////////////////////////////////////////////////
1013
//    // Main Behavior Process
1014
//    // combinational process for next state generation
1015
//    /////////////////////////////////////////////////////////////////////////
1016
 
1017
    integer sect;
1018
    reg rising_edge_PDONE = 1'b0;
1019
    reg rising_edge_EDONE = 1'b0;
1020
    reg rising_edge_WDONE = 1'b0;
1021
    reg rising_edge_DP_out = 1'b0;
1022
    reg falling_edge_write = 1'b0;
1023
 
1024
    always @(falling_edge_write or rising_edge_PDONE or rising_edge_WDONE
1025
    or rising_edge_EDONE or rising_edge_DP_out)
1026
    begin: StateGen1
1027
        if (falling_edge_write)
1028
        begin
1029
            case (current_state)
1030
                IDLE :
1031
                begin
1032
                    if (~write)
1033
                    begin
1034
                        if (Instruct == WRSR && Status_reg[1])
1035
                        begin
1036
                            if (~(Status_reg[7] && (~WPNeg_ipd)))
1037
                                next_state = WRITE_SR;
1038
                        end
1039
                        else if (Instruct == PP && Status_reg[1])
1040
                        begin
1041
                            sect = Address / 24'h40000;
1042
                            if (Sec_Prot[sect] == 1'b0)
1043
                                next_state = PAGE_PG;
1044
                        end
1045
                        else if (Instruct == SE && Status_reg[1])
1046
                        begin
1047
                            sect = Address / 24'h40000;
1048
                            if (Sec_Prot[sect] == 1'b0)
1049
                                next_state = SECTOR_ER;
1050
                        end
1051
                        else if (Instruct == BE && Status_reg[1])
1052
                        begin
1053
                            if (Status_reg[2]==1'b0 && Status_reg[3]==1'b0 &&
1054
                                Status_reg[4]==1'b0 )
1055
                                next_state = BULK_ER;
1056
                        end
1057
                        else if (Instruct == DP)
1058
                            next_state = DP_DOWN_WAIT;
1059
                        else
1060
                            next_state = IDLE;
1061
                    end
1062
                end
1063
 
1064
                DP_DOWN:
1065
                begin
1066
                    if (~write)
1067
                    begin
1068
                        if (Instruct == RES_READ_ES)
1069
                            next_state = IDLE;
1070
                    end
1071
                end
1072
 
1073
            endcase
1074
        end
1075
 
1076
        if (rising_edge_PDONE)
1077
        begin
1078
            if (current_state==PAGE_PG)
1079
            begin
1080
                next_state = IDLE;
1081
            end
1082
        end
1083
 
1084
        if (rising_edge_WDONE)
1085
        begin
1086
            if (current_state==WRITE_SR)
1087
            begin
1088
                next_state = IDLE;
1089
            end
1090
        end
1091
 
1092
        if (rising_edge_EDONE)
1093
        begin
1094
            if (current_state==SECTOR_ER || current_state==BULK_ER)
1095
            begin
1096
                next_state = IDLE;
1097
            end
1098
        end
1099
 
1100
        if (rising_edge_DP_out)
1101
        begin
1102
            if (current_state==DP_DOWN_WAIT)
1103
            begin
1104
                next_state = DP_DOWN;
1105
            end
1106
        end
1107
    end
1108
 
1109
    ///////////////////////////////////////////////////////////////////////////
1110
    //FSM Output generation and general functionality
1111
    ///////////////////////////////////////////////////////////////////////////
1112
    reg rising_edge_read_out = 1'b0;
1113
    reg Instruct_event       = 1'b0;
1114
    reg change_addr_event    = 1'b0;
1115
    reg current_state_event  = 1'b0;
1116
 
1117
    integer sector;
1118
    integer WData [0:255];
1119
    integer Addr;
1120
 
1121
    always @(oe_event)
1122
    begin
1123
        oe = 1'b1;
1124
        #1 oe = 1'b0;
1125
    end
1126
 
1127
    always @(rising_edge_read_out or Instruct_event or
1128
    change_addr_event or oe or current_state_event or falling_edge_write
1129
    or EDONE or WDONE or PDONE or CSNeg_ipd or HOLDNeg_ipd or RES_out or DP_out)
1130
    begin: Functionality
1131
    integer i,j;
1132
 
1133
        if (rising_edge_read_out)
1134
        begin
1135
            if (HOLDNeg_ipd == 1'b1 && PoweredUp == 1'b1)
1136
                ->oe_event;
1137
        end
1138
 
1139
        if (Instruct_event)
1140
        begin
1141
            read_cnt = 0;
1142
            rd_fast = 1'b1;
1143
            rd_slow = 1'b0;
1144
        end
1145
 
1146
        if (Instruct_event == 1'b1 && current_state == DP_DOWN_WAIT)
1147
        begin
1148
             if (DP_in == 1'b1)
1149
             begin
1150
                  $display ("Command results can be corrupted");
1151
             end
1152
        end
1153
 
1154
        if (change_addr_event)
1155
        begin
1156
            read_addr = Address;
1157
        end
1158
 
1159
        if (oe || current_state_event)
1160
        begin
1161
            case (current_state)
1162
                IDLE :
1163
                begin
1164
                    if (oe && RES_in == 1'b0)
1165
                    begin
1166
                        if (Instruct == RDSR)
1167
                        begin
1168
                        //Read Status Register
1169
                            if (serial_mode)
1170
                            begin
1171
                                POut_zd[7] = Status_reg[7-read_cnt];
1172
                                read_cnt = read_cnt + 1;
1173
                                if (read_cnt == 8)
1174
                                    read_cnt = 0;
1175
                            end
1176
                            else
1177
                            begin
1178
                                POut_zd = Status_reg;
1179
                            end
1180
                        end
1181
                        else if (Instruct == READ || Instruct == FAST_READ)
1182
                        begin
1183
                        //Read Memory array
1184
                            if (Instruct == READ)
1185
                            begin
1186
                                rd_fast = 1'b0;
1187
                                rd_slow = 1'b1;
1188
                            end
1189
                            data_out[7:0] = Mem[read_addr];
1190
                            if (serial_mode)
1191
                            begin
1192
                                POut_zd[7] = data_out[7-read_cnt];
1193
                                read_cnt = read_cnt + 1;
1194
                                if (read_cnt == 8)
1195
                                begin
1196
                                    read_cnt = 0;
1197
                                    if (read_addr == AddrRANGE)
1198
                                        read_addr = 0;
1199
                                    else
1200
                                        read_addr = read_addr + 1;
1201
                                end
1202
                            end
1203
                            else
1204
                            begin
1205
                                POut_zd = data_out[7:0];
1206
                                if (read_addr == AddrRANGE)
1207
                                    read_addr = 0;
1208
                                else
1209
                                    read_addr = read_addr + 1;
1210
                            end
1211
                        end
1212
                        else if (Instruct == RDID)
1213
                        begin
1214
                        // Read ID
1215
                            ident_out[39:0] = {DeviceID,ExtendedID};
1216
                            if (serial_mode)
1217
                            begin
1218
                                POut_zd[7] = ident_out[39-read_cnt];
1219
                                read_cnt = read_cnt + 1;
1220
                                if (read_cnt == 40)
1221
                                    read_cnt = 0;
1222
                            end
1223
                            else
1224
                            begin
1225
                                if (prl_read_cnt == 0)
1226
                                begin
1227
                                    POut_zd = ident_out[39:32];
1228
                                    prl_read_cnt = prl_read_cnt +1;
1229
                                end
1230
                                else if (prl_read_cnt == 1)
1231
                                begin
1232
                                    POut_zd = ident_out[31:24];
1233
                                    prl_read_cnt = prl_read_cnt +1;
1234
                                end
1235
                                else if (prl_read_cnt == 2)
1236
                                begin
1237
                                    POut_zd = ident_out[23:16];
1238
                                    prl_read_cnt = prl_read_cnt +1;
1239
                                end
1240
                                else if (prl_read_cnt == 3)
1241
                                begin
1242
                                    POut_zd = ident_out[15:8];
1243
                                    prl_read_cnt = prl_read_cnt +1;
1244
                                end
1245
                                else if (prl_read_cnt == 4)
1246
                                begin
1247
                                    POut_zd = ident_out[7:0];
1248
                                    prl_read_cnt = 0;
1249
                                end
1250
                            end
1251
                        end
1252
                        else if (Instruct == READ_ID)
1253
                        begin
1254
                        // --Read Manufacturer and Device ID
1255
                            if (read_addr == 0)
1256
                            begin
1257
                                data_out[7:0] = Manuf_ID;
1258
                                if (serial_mode)
1259
                                begin
1260
                                    POut_zd[7] = data_out[7-read_cnt];
1261
                                    read_cnt = read_cnt + 1;
1262
                                    if (read_cnt == 8)
1263
                                    begin
1264
                                        read_cnt = 0;
1265
                                        read_addr = read_addr + 1;
1266
                                    end
1267
                                end
1268
                                else
1269
                                begin
1270
                                    POut_zd = data_out[7:0];
1271
                                    read_addr = read_addr + 1;
1272
                                end
1273
                            end
1274
                            else if (read_addr == 1)
1275
                            begin
1276
                                data_out[7:0] = ES;
1277
                                if (serial_mode)
1278
                                begin
1279
                                    POut_zd[7] = data_out[7-read_cnt];
1280
                                    read_cnt = read_cnt + 1;
1281
                                    if (read_cnt == 8)
1282
                                    begin
1283
                                        read_cnt = 0;
1284
                                        read_addr = 0;
1285
                                    end
1286
                                end
1287
                                else
1288
                                begin
1289
                                    POut_zd = data_out[7:0];
1290
                                    read_addr = 0;
1291
                                end
1292
                            end
1293
                        end
1294
                    end
1295
                    else if (oe && RES_in == 1'b1)
1296
                    begin
1297
                        $display ("Command results can be corrupted");
1298
                        if (serial_mode)
1299
                        begin
1300
                            POut_zd[7] = 1'bX;
1301
                            read_cnt = read_cnt + 1;
1302
                            if (read_cnt == 8)
1303
                                read_cnt = 0;
1304
                        end
1305
                    end
1306
                end
1307
 
1308
                WRITE_SR,
1309
                SECTOR_ER,
1310
                BULK_ER,
1311
                PAGE_PG :
1312
                begin
1313
                    if (oe && Instruct == RDSR)
1314
                    begin
1315
                    //Read Status Register
1316
                        if (serial_mode)
1317
                        begin
1318
                            POut_zd[7] = Status_reg[7-read_cnt];
1319
                            read_cnt = read_cnt + 1;
1320
                            if (read_cnt == 8)
1321
                                read_cnt = 0;
1322
                        end
1323
                        else
1324
                        begin
1325
                            POut_zd = Status_reg;
1326
                        end
1327
                    end
1328
                end
1329
 
1330
                DP_DOWN :
1331
                begin
1332
                    if (oe && Instruct == RES_READ_ES)
1333
                    begin
1334
                    // Read ID
1335
                        if (serial_mode)
1336
                        begin
1337
                            data_out[7:0] = Jedec_ID;
1338
                            POut_zd[7] = data_out[7-read_cnt];
1339
                            read_cnt = read_cnt + 1;
1340
                            if (read_cnt == 8)
1341
                                read_cnt = 0;
1342
                        end
1343
                        else
1344
                        begin
1345
                            data_out[7:0] = Jedec_ID;
1346
                            POut_zd = data_out[7:0];
1347
                        end
1348
                    end
1349
                end
1350
 
1351
            endcase
1352
        end
1353
 
1354
        if (falling_edge_write)
1355
        begin
1356
            case (current_state)
1357
                IDLE :
1358
                begin
1359
                    if (~write)
1360
                    begin
1361
                        if (RES_in == 1'b1 && Instruct != RES_READ_ES)
1362
                        begin
1363
                            $display ("Command results can be corrupted");
1364
                        end
1365
                        if (Instruct == WREN)
1366
                            Status_reg[1] = 1'b1;
1367
                        else if (Instruct == WRDI)
1368
                            Status_reg[1] = 1'b0;
1369
                        else if (Instruct == WRSR && Status_reg[1] &&
1370
                                (~(Status_reg[7] == 1'b1 && WPNeg_ipd == 1'b0)))
1371
                        begin
1372
                            WSTART = 1'b1;
1373
                            WSTART <= #1 1'b0;
1374
                            Status_reg[0] = 1'b1;
1375
                        end
1376
                        else if (Instruct == PP && Status_reg[1] == 1'b1)
1377
                        begin
1378
                            sect = Address / 24'h40000;
1379
                            if (Sec_Prot[sect] == 1'b0)
1380
                            begin
1381
                                PSTART = 1'b1;
1382
                                PSTART <= #1 1'b0;
1383
                                Status_reg[0] = 1'b1;
1384
                                Addr = Address;
1385
                                SA = sector;
1386
                                wr_cnt = Byte_number;
1387
                                for (i=0;i<=wr_cnt;i=i+1)
1388
                                begin
1389
                                    if (Viol!=1'b0)
1390
                                        WData[i] = -1;
1391
                                    else
1392
                                        WData[i] = WByte[i];
1393
                                end
1394
                            end
1395
                        end
1396
                        else if (Instruct == SE && Status_reg[1] == 1'b1)
1397
                        begin
1398
                            sect = Address / 24'h40000;
1399
                            if (Sec_Prot[sect] == 1'b0)
1400
                            begin
1401
                                ESTART = 1'b1;
1402
                                ESTART <= #1 1'b0;
1403
                                Status_reg[0] = 1'b1;
1404
                                Addr = Address;
1405
                            end
1406
                        end
1407
                        else if (Instruct == BE && Status_reg[1] == 1'b1 &&
1408
                                Status_reg[2]==1'b0 && Status_reg[3]==1'b0 &&
1409
                                Status_reg[4]==1'b0)
1410
                        begin
1411
                            ESTART = 1'b1;
1412
                            ESTART <= #1 1'b0;
1413
                            Status_reg[0] = 1'b1;
1414
                        end
1415
                        else if (Instruct == DP)
1416
                        begin
1417
                            RES_in = 1'b0;
1418
                            DP_in = 1'b1;
1419
                        end
1420
                    end
1421
 
1422
                end
1423
 
1424
                DP_DOWN :
1425
                begin
1426
                    if (~write)
1427
                    begin
1428
                        if (Instruct == RES_READ_ES)
1429
                            RES_in = 1'b1;
1430
                    end
1431
                end
1432
 
1433
            endcase
1434
        end
1435
 
1436
        if(current_state_event || EDONE)
1437
        begin
1438
            case (current_state)
1439
 
1440
                SECTOR_ER :
1441
                begin
1442
                    ADDRHILO_SEC(AddrLo, AddrHi, Addr);
1443
                    for (i=AddrLo;i<=AddrHi;i=i+1)
1444
                    begin
1445
                        Mem[i] = -1;
1446
                    end
1447
 
1448
                    if (EDONE)
1449
                    begin
1450
                        Status_reg[0] = 1'b0;
1451
                        Status_reg[1] = 1'b0;
1452
                        Status_reg[6] = 1'b0;
1453
                        for (i=AddrLo;i<=AddrHi;i=i+1)
1454
                        begin
1455
                            Mem[i] = MaxData;
1456
                        end
1457
                    end
1458
                end
1459
 
1460
                BULK_ER :
1461
                begin
1462
                    for (i=0;i<=AddrRANGE;i=i+1)
1463
                    begin
1464
                        Mem[i] = -1;
1465
                    end
1466
 
1467
                    if (EDONE)
1468
                    begin
1469
                        Status_reg[0] = 1'b0;
1470
                        Status_reg[1] = 1'b0;
1471
                        Status_reg[6] = 1'b0;
1472
                        for (i=0;i<=AddrRANGE;i=i+1)
1473
                        begin
1474
                            Mem[i] = MaxData;
1475
                        end
1476
                    end
1477
                end
1478
            endcase
1479
        end
1480
 
1481
        if(current_state_event || WDONE)
1482
        begin
1483
            if (current_state == WRITE_SR)
1484
            begin
1485
                if (WDONE)
1486
                begin
1487
                    Status_reg[0] = 1'b0;//WIP
1488
                    Status_reg[1] = 1'b0;//WEL
1489
                    Status_reg[6] = 1'b0;
1490
                    Status_reg[7] = Status_reg_in[0];//MSB first, SRWD
1491
                    Status_reg[4] = Status_reg_in[3];//MSB first, BP2
1492
                    Status_reg[3] = Status_reg_in[4];//MSB first, BP1
1493
                    Status_reg[2] = Status_reg_in[5];//MSB first, BP0
1494
                    case (Status_reg[4:2])
1495
                        3'b000 :
1496
                        begin
1497
                            Sec_Prot = 64'h0;
1498
                        end
1499
 
1500
                        3'b001 :
1501
                        begin
1502
                            Sec_Prot[63] = 1'h1;
1503
                            Sec_Prot[62:0] = 63'h0;
1504
                        end
1505
 
1506
                        3'b010 :
1507
                        begin
1508
                            Sec_Prot[63:62] = 2'h3;
1509
                            Sec_Prot[61:0] = 62'h0;
1510
                        end
1511
 
1512
                        3'b011 :
1513
                        begin
1514
                            Sec_Prot[63:60] = 4'hF;
1515
                            Sec_Prot[59:0] = 60'h0;
1516
                        end
1517
 
1518
                        3'b100 :
1519
                        begin
1520
                            Sec_Prot[63:56] = 8'hFF;
1521
                            Sec_Prot[55:0] = 56'h0;
1522
                        end
1523
 
1524
                        3'b101 :
1525
                        begin
1526
                            Sec_Prot[63:48] = 16'hFFFF;
1527
                            Sec_Prot[47:0] = 48'h0;
1528
                        end
1529
 
1530
                        3'b110 :
1531
                        begin
1532
                            Sec_Prot[63:32] = 32'hFFFFFFFF;
1533
                            Sec_Prot[31:0] = 32'h0;
1534
                        end
1535
 
1536
                        3'b111 :
1537
                        begin
1538
                            Sec_Prot = 64'hFFFFFFFFFFFFFFFF;
1539
                        end
1540
                    endcase
1541
                end
1542
            end
1543
        end
1544
 
1545
        if(current_state_event || PDONE)
1546
        begin
1547
            if (current_state == PAGE_PG)
1548
            begin
1549
                ADDRHILO_PG(AddrLo, AddrHi, Addr);
1550
                if ((Addr + wr_cnt) > AddrHi)
1551
                    wr_cnt = AddrHi - Addr;
1552
                for (i=Addr;i<=Addr+wr_cnt;i=i+1)
1553
                begin
1554
                    new_int = WData[i-Addr];
1555
                    old_int = Mem[i];
1556
                    if (new_int > -1)
1557
                    begin
1558
                        new_bit = new_int;
1559
                        if (old_int > -1)
1560
                        begin
1561
                            old_bit = old_int;
1562
                            for(j=0;j<=7;j=j+1)
1563
                                if (~old_bit[j])
1564
                                    new_bit[j]=1'b0;
1565
                            new_int=new_bit;
1566
                        end
1567
 
1568
                        WData[i-Addr]= new_int;
1569
                    end
1570
                    else
1571
                    begin
1572
                        WData[i-Addr] = -1;
1573
                    end
1574
                end
1575
 
1576
                for (i=Addr;i<=Addr+wr_cnt;i=i+1)
1577
                begin
1578
                    Mem[i] = -1;
1579
                end
1580
 
1581
                if (PDONE)
1582
                begin
1583
                    Status_reg[0] = 1'b0;//wip
1584
                    Status_reg[1] = 1'b0;// wel
1585
                    Status_reg[6] = 1'b0;
1586
                    for (i=Addr;i<=Addr+wr_cnt;i=i+1)
1587
                    begin
1588
                        Mem[i] = WData[i-Addr];
1589
                    end
1590
                end
1591
            end
1592
        end
1593
 
1594
        //Output Disable Control
1595
        if (CSNeg_ipd )
1596
        begin
1597
            if (serial_mode)
1598
                POut_zd[7] = 1'bZ;
1599
            else
1600
                POut_zd = 8'bZZZZZZZZ;
1601
        end
1602
 
1603
        if (RES_out)
1604
        begin
1605
            RES_in = 1'b0;
1606
        end
1607
 
1608
        if (DP_out)
1609
        begin
1610
            DP_in = 1'b0;
1611
        end
1612
 
1613
    end
1614
 
1615
    assign fast_rd = rd_fast;
1616
    assign rd = rd_slow;
1617
 
1618
    always @(POut_zd or HOLDNeg_ipd)
1619
    begin
1620
        if (HOLDNeg_ipd == 1)
1621
        begin
1622
           if (serial_mode)
1623
               POut_z[7] = POut_zd[7];
1624
           else
1625
               POut_z = POut_zd;
1626
        end
1627
        else
1628
        begin
1629
           if (serial_mode)
1630
           begin
1631
               POut_z[7] = 1'bZ;
1632
           end
1633
           else
1634
           begin
1635
               POut_z = 8'bZZZZZZZZ;
1636
           end
1637
        end
1638
    end
1639
 
1640
// Procedure ADDRHILO_SEC
1641
 task ADDRHILO_SEC;
1642
 inout  AddrLOW;
1643
 inout  AddrHIGH;
1644
 input   Addr;
1645
 integer AddrLOW;
1646
 integer AddrHIGH;
1647
 integer Addr;
1648
 integer sector;
1649
 begin
1650
    sector = Addr / 20'h40000;
1651
    AddrLOW = sector * 20'h40000;
1652
    AddrHIGH = sector * 20'h40000 + 20'h3FFFF;
1653
 end
1654
 endtask
1655
 
1656
// Procedure ADDRHILO_PG
1657
 task ADDRHILO_PG;
1658
 inout  AddrLOW;
1659
 inout  AddrHIGH;
1660
 input   Addr;
1661
 integer AddrLOW;
1662
 integer AddrHIGH;
1663
 integer Addr;
1664
 integer page;
1665
 begin
1666
 
1667
    page = Addr / 16'h100;
1668
    AddrLOW = page * 16'h100;
1669
    AddrHIGH = page * 16'h100 + 8'hFF;
1670
 
1671
 end
1672
 endtask
1673
 
1674
    always @(negedge CSNeg_ipd)
1675
    begin
1676
        falling_edge_CSNeg_ipd = 1'b1;
1677
        #1 falling_edge_CSNeg_ipd = 1'b0;
1678
    end
1679
 
1680
    always @(posedge SCK_ipd)
1681
    begin
1682
        rising_edge_SCK_ipd = 1'b1;
1683
        #1 rising_edge_SCK_ipd = 1'b0;
1684
    end
1685
 
1686
    always @(negedge SCK_ipd)
1687
    begin
1688
        falling_edge_SCK_ipd = 1'b1;
1689
        #1 falling_edge_SCK_ipd = 1'b0;
1690
    end
1691
 
1692
    always @(posedge CSNeg_ipd)
1693
    begin
1694
        rising_edge_CSNeg_ipd = 1'b1;
1695
        #1 rising_edge_CSNeg_ipd = 1'b0;
1696
    end
1697
 
1698
    always @(negedge write)
1699
    begin
1700
        falling_edge_write = 1'b1;
1701
        #1 falling_edge_write = 1'b0;
1702
    end
1703
 
1704
    always @(posedge PDONE)
1705
    begin
1706
        rising_edge_PDONE = 1'b1;
1707
        #1 rising_edge_PDONE = 1'b0;
1708
    end
1709
 
1710
    always @(posedge WDONE)
1711
    begin
1712
        rising_edge_WDONE = 1'b1;
1713
        #1 rising_edge_WDONE = 1'b0;
1714
    end
1715
 
1716
    always @(posedge EDONE)
1717
    begin
1718
        rising_edge_EDONE = 1'b1;
1719
        #1 rising_edge_EDONE = 1'b0;
1720
    end
1721
 
1722
    always @(posedge DP_out)
1723
    begin
1724
        rising_edge_DP_out = 1'b1;
1725
        #1 rising_edge_DP_out = 1'b0;
1726
    end
1727
 
1728
    always @(read_out)
1729
    begin
1730
        rising_edge_read_out = 1'b1;
1731
        #1 rising_edge_read_out = 1'b0;
1732
    end
1733
 
1734
    always @(Instruct)
1735
    begin
1736
        Instruct_event = 1'b1;
1737
        #1 Instruct_event = 1'b0;
1738
    end
1739
 
1740
    always @(change_addr)
1741
    begin
1742
        change_addr_event = 1'b1;
1743
        #1 change_addr_event = 1'b0;
1744
    end
1745
 
1746
    always @(current_state)
1747
    begin
1748
        current_state_event = 1'b1;
1749
        #1 current_state_event = 1'b0;
1750
    end
1751
 
1752
endmodule

powered by: WebSVN 2.1.0

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