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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [bench/] [verilog/] [AT26DFxxx.v] - Blame information for rev 480

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

Line No. Rev Author Line
1 6 julius
//--------------------------------------------------------------------------
2
// This is the property of PERFTRENDS TECHNOLOGIES PRIVATE LIMITED and
3
// possession or use of file has to be with the written LICENCE AGGREMENT
4
// from PERFTRENDS TECHNOLOGIES PRIVATE LIMITED.
5
//
6
//--------------------------------------------------------------------------
7
//
8
// Project : ATMEL Data Flash Device
9
//--------------------------------------------------------------------------
10
// File         : $RCSfile: AT26DFxxx.v,v $
11
// Path         : $Source: /home/cvs/atmel_flash_dev/design_26x/AT26DFxxx.v,v $
12
// Author       : $ Devi Vasumathy N $
13
// Created on   : $ 13-03-07 $
14
// Revision     : $Revision: 1.8 $
15
// Last modified by : $Author: devivasumathy $
16
// Last modified on : $Date: 2007/05/10 05:15:51 $
17
//--------------------------------------------------------------------------
18
// Module               : AT26DFxxx.v
19
// Description          : BFM for devices AT25DF041A, AT26DF081A, 
20
//                        AT26DF161A, AT26DF321
21
//
22
//--------------------------------------------------------------------------
23
//
24
// Design hierarchy : _top.v/top_1.v/top_2.v/...
25
// Instantiated Modules : top_1.v, top_2.v
26
//--------------------------------------------------------------------------
27
// Revision history :
28
// $Log: AT26DFxxx.v,v $
29
// Revision 1.8  2007/05/10 05:15:51  devivasumathy
30
// Card Memory preload
31
//
32
// Revision 1.7  2007/04/27 09:09:40  devivasumathy
33
// *** empty log message ***
34
//
35
// Revision 1.6  2007/04/17 10:50:59  devivasumathy
36
// Timing verified
37
//
38
// Revision 1.5  2007/04/16 06:24:44  devivasumathy
39
// *** empty log message ***
40
//
41
// Revision 1.4  2007/04/10 09:37:36  devivasumathy
42
// *** empty log message ***
43
//
44
// Revision 1.3  2007/04/09 12:06:09  devivasumathy
45
// *** empty log message ***
46
//
47
// Revision 1.2  2007/04/05 14:45:12  devivasumathy
48
// *** empty log message ***
49
//
50
// Revision 1.1  2007/04/05 11:32:18  devivasumathy
51
// AT26DFx data flash model
52
//
53
//--------------------------------------------------------------------------
54
 
55
`timescale 1ns/10ps      //ME added
56
 
57
`define def_321 1        //ME added
58
 
59
 
60
module AT26DFxxx (
61
                CSB,
62
                SCK,
63
                SI,
64
                WPB,
65
`ifdef def_321
66
`else
67
                HOLDB,
68
`endif
69
                SO);
70
 
71
// ******************************************************************** //
72
//                      Port Declaration:
73
// ******************************************************************** //
74
 
75
input   CSB;            // Chip Select!
76
input   SCK;            // Serial Clock
77
input   SI;             // Serial Input
78
input   WPB;            // Write Protect!
79
`ifdef def_321
80
`else
81
input   HOLDB;          // Hold!
82
`endif
83
output  SO;             // Serial Output
84
 
85
`ifdef def_321
86
        wire  HOLDB;
87
`endif
88
 
89
parameter DEVICE = "AT25DF041A";        // Device selected
90
parameter PRELOAD = 1;                  // preload memory with content in MEMORY_FILE
91
parameter MEMORY_FILE = "flash.in";     // Memory pre-load
92 403 julius
   parameter VERBOSE = 1;
93
 
94 6 julius
// ********************************************************************* //
95
//Timing Parameters :
96
// ******************************************************************** //
97
 
98
// Fixed parameters
99
parameter fRDLF   = 33;         // SCK Frequency for read Array (Low freq - 03h opcode)
100
//representation in ns
101
parameter tDIS    = 6;          // Output Disable time
102
parameter tV      = 6;          // Output Valid time
103
parameter tOH     = 0 ;          // Output Hold time
104
 
105
parameter tHLQZ   = 6 ;         // HOLD! Low to Output High-z
106
parameter tHHQX   = 6 ;         // HOLD! High to Output Low-z
107
 
108
parameter tSECP   = 20;         // Sector Protect Time
109
parameter tSECUP  = 20;         // Sector Unprotect Time
110
 
111
parameter tEDPD   = 3000;       // Chip Select high to Deep Power-down (3 us)
112
parameter tRDPD   = 3000;       // Chip Select high to Stand-by Mode
113
parameter tWRSR   = 200;        // Write Status Register Time
114
parameter tPP     = 5000000;    // Page Program Time
115
parameter tBLKE4  = 200000000;  // Block Erase Time 4-kB
116
parameter tBLKE32 = 600000000;  // Block Erase Time 32-kB
117
parameter tCHPEn  = 1000000000; // local chip erase time
118
 
119
// variable parameters
120
// ******************************************************************** //
121
//parameter tBP     = 7000;             // Byte Program Time
122
//parameter tBLKE64 = 950000000;        // Block Erase Time 64-kB
123
//parameter tCHPE   = 3000000000;       // Chip Erase Time // this is actual;
124
                                        // due to simulation warning splitted into 2 parameters as tCHPE = tmult * tCHPEn
125
//parameter tmult   = 3;                // Multiplication factor for chip erase timing
126
 
127
parameter tBP =         (DEVICE == "AT25DF041A") ? 7000 :
128
                        (DEVICE == "AT26DF081A") ? 7000 :
129
                        (DEVICE == "AT26DF161A") ? 7000 :
130
                        (DEVICE == "AT26DF321")  ? 6000 : 7000;
131
 
132
parameter tBLKE64 =     (DEVICE == "AT25DF041A") ? 950000000 :
133
                        (DEVICE == "AT26DF081A") ? 950000000 :
134
                        (DEVICE == "AT26DF161A") ? 950000000 :
135
                        (DEVICE == "AT26DF321")  ? 1000000000 :950000000 ;
136
 
137
parameter tmult =       (DEVICE == "AT25DF041A") ? 3 :
138
                        (DEVICE == "AT26DF081A") ? 6 :
139
                        (DEVICE == "AT26DF161A") ? 12 :
140
                        (DEVICE == "AT26DF321")  ? 36 : 3;
141
 
142
//parameter fSCK    = 70;       // Serial clock (SCK) Frequency in MHz
143
//parameter tSCKH   = 6.4;      // SCK High time
144
//parameter tSCKL   = 6.4;      // SCK Low time
145
 
146
parameter fSCK =        (DEVICE == "AT25DF041A") ? 70 :
147
                        (DEVICE == "AT26DF081A") ? 70 :
148
                        (DEVICE == "AT26DF161A") ? 70 :
149
                        (DEVICE == "AT26DF321")  ? 66 : 70;
150
 
151
parameter tSCKH =       (DEVICE == "AT25DF041A") ? 6.4 :
152
                        (DEVICE == "AT26DF081A") ? 6.4 :
153
                        (DEVICE == "AT26DF161A") ? 6.4 :
154
                        (DEVICE == "AT26DF321")  ? 6.8 : 6.4;
155
 
156
parameter tSCKL =       (DEVICE == "AT25DF041A") ? 6.4 :
157
                        (DEVICE == "AT26DF081A") ? 6.4 :
158
                        (DEVICE == "AT26DF161A") ? 6.4 :
159
                        (DEVICE == "AT26DF321")  ? 6.8 : 6.4;
160
// ******************************************************************** //
161
 
162
// ********************** Manufacturer ID ********************** //
163
parameter [31:0] MAN_ID = (DEVICE == "AT25DF041A") ? 32'h1F_04_00_00 :
164
                        (DEVICE == "AT26DF081A") ? 32'h1F_45_01_00 :
165
                        (DEVICE == "AT26DF161A") ? 32'h1F_46_01_00 :
166
                        (DEVICE == "AT26DF321")  ? 32'h1F_47_00_00 : 32'h1F_04_00_00;
167
 
168
// ********* Memory And Access Related Declarations ***************** //
169
 
170
parameter BLOCK64 =     (DEVICE == "AT25DF041A") ? 8  : // no of 64kB blocks
171
                        (DEVICE == "AT26DF081A") ? 16 :
172
                        (DEVICE == "AT26DF161A") ? 32 :
173
                        (DEVICE == "AT26DF321")  ? 64 : 8 ;
174
 
175
parameter SECTOR =      (DEVICE == "AT25DF041A") ? 11 : // no of sectors
176
                        (DEVICE == "AT26DF081A") ? 19 :
177
                        (DEVICE == "AT26DF161A") ? 32 :
178
                        (DEVICE == "AT26DF321")  ? 64 : 11 ;
179
 
180
// total memory size = no. of blocks * 64 k bits (i.e each block contains 64 KB)
181
parameter MEMSIZE = BLOCK64 * 64 * 1024; // total memory size
182
 
183
reg [7:0] memory [MEMSIZE-1:0]; // memory of selected device
184
reg [7:0] status_reg;            // Status register
185
reg [63:0] sector_reg;           // Sector protection reg
186
reg [7:0] int_buffer [255:0];     // internal buffer to store data in page programming mode
187
// ****************** ***************** ***************** //
188
 
189
 
190
// ********* Registers to track the current operation of the device ******** //
191
reg deep_power_down;            // Device in Deep Power Down Mode
192
reg status_read;                // Status register is being read
193
reg erasing_block4;             // 4kB block erase
194
reg erasing_block32;            // 32kB block erase
195
reg erasing_block64;            // 64kB block erase
196
reg erasing_chip;               // chip erase
197
reg rd_dummy;                   // low/high freq read array
198
reg byte_prog;                  // Byte/page programming
199
reg seq_byte_prog;              // sequential byte programming
200
reg seq_byte_start;             // sequential byte programming start intimation
201
 
202
 
203
// ********* Events to trigger some task based on opcode *********** //
204
event  EDPD;            // Deep Power-down (enable)
205
event  RDPD;            // Resume from Deep Power-down
206
event  RA;              // Read Array
207
//event  RAL;           // Read Array (Low frequency)
208
event  BE4;             // Block Erase 4KB
209
event  BE32;            // Block Erase 32KB
210
event  BE64;            // Block Erase 64KB
211
event  CE;              // Chip Erase
212
event  BP;              // byte /page program
213
//event  SBPE;          // Sequential Byte Program Mode Erase
214
event  SBP;             // Sequential Byte Program
215
event  WE;              // Write Enable
216
event  WD;              // Write Disable
217
event  PS;              // Protect Sector
218
event  UPS;             // Un-Protect Sector
219
event  RSPR;            // Read Sector Protection Register
220
event  RSR;             // Read Status Register
221
event  WSR;             // Write Status Register
222
event  MIR;             // Manufacturer ID Read 
223
 
224
 
225
/******** Other variables/registers ******************/
226
reg [23:0] temp_addr;            // to store mem address temporarily
227
reg [23:0] current_address;      // to store mem address
228
reg [7:0] temp_data;             // temp read data from memory
229
reg [7:0] data_in;               // data in for byte programming
230
reg [7:0] read_data;             // register in which opcode/data is read-in
231
reg [7:0] read_dummy;            // register in which dont care data is stored
232
reg [3:0] stat_reg_temp; // WSR temp value for global protec/unprotect
233
reg [7:0] pp_address;            // specifies the page address for BP/PP
234
reg SO_reg;                     // Signal out reg
235
reg SO_on;                      // Signal out enable signal
236
reg SPRL;                       // Sector Protection Register Locked
237
reg SPM;                        // Sequential Program Mode Status
238
reg EPE;                        // Erase/Program Error
239
reg WPP;                        // Write Protection Pin Status
240
reg [1:0] SWP;                   // Software Protection Status
241
reg WEL;                        // Write Enable Latch Status
242
reg RDYnBSY;                    // Ready/Busy Status
243
reg lock;                       // to lock SPRL bit of status reg
244
reg unlock;                     // to unlock SPRL bit of status reg
245
reg global_protect;             // global protection
246
reg global_unprotect;           // global unprotect
247
reg protect;                    // to protect Sector reg bits
248
reg unprotect;                  // to unprotect Sector reg bits
249
reg protected;                  // check protection status of sector reg
250
reg SPRL_val;                   // WSR temp value for SPRL
251
integer i,j,k,l;                // integers for accessing memory
252
integer pp;                     // specifies no of bytes need to write in memory
253
integer pp_j;                   // holds no of bytes received for page program
254
integer pp_i;                   // holds no of bits received for each byte in page program
255
integer dummy;                  // counter for receiving 8 dummy bit from SO
256
integer delay;                  // waits for Chip Erase to complete
257
 
258
real tperiod;                   // time period - on period
259
real tperiod1;                  // time period - off period
260
reg freq_error;                 // frequency limit exceeds indication
261
 
262
 
263
// ****************** Initial Block **************** //
264
`ifdef def_321
265
        assign HOLDB = 1'b1;
266
`endif
267
 
268
initial
269
begin
270
 
271
// Memory Initialization
272
//To pre-load Memory (in Hex format), use parameter MEMORY_FILE = <filename>, 
273
//where <filename> is the name of the pre-load file. 
274
//If PRELOAD = 0, the Memory is initialized to Erased state (all data = FF).
275
//If PRELOAD = 1, the Memory is initialized to PreLoad state (data in pre-load file).
276
 
277
        for(i=0; i<BLOCK64; i=i+1)                       // Block64K access
278
        begin
279
            for(j=0; j<2; j=j+1)                 // Block32K access
280
            begin
281
                for(k=0; k<8; k=k+1)                     // Block4K access
282
                begin
283
                    for(l=0; l < 12'hfff; l=l+1)
284
                    begin
285
                        memory[l] = 8'b11111111;
286
                    end
287
                end
288
            end
289
        end
290
 
291
// Memory Initialization for preloading condition
292
if(PRELOAD==1)
293
begin
294
        $readmemh (MEMORY_FILE, memory);
295
end
296
 
297
 
298
// Status register initialization
299
SPRL = 1'b0;
300
SPM = 1'b0;
301
EPE = 1'b0;
302
WPP = 1'b0;
303
SWP = 2'b11;
304
WEL = 1'b0;
305
RDYnBSY = 1'b0; // device is ready
306
status_reg[7]   = SPRL;
307
status_reg[6]   = SPM;
308
status_reg[5]   = EPE; // reserved
309
status_reg[4]   = WPP;
310
status_reg[3:2] = SWP;
311
status_reg[1]   = WEL;
312
status_reg[0]    = RDYnBSY;
313
//status_reg = {1'b1,1'b0,1'b0,1'b0,2'b11,2'b0};
314
 
315
sector_reg = 64'hFFFFFFFFFFFFFFFF;
316
 
317
// Stand-by mode initialization
318
current_address  = 24'b0;
319
data_in          = 8'b0;
320
stat_reg_temp    = 4'b0;
321
deep_power_down  = 1'b0;
322
status_read      = 1'b0;
323
rd_dummy         = 1'b0;
324
seq_byte_start   = 1'b0;
325
SO_on            = 1'b0;
326
global_protect   = 1'b0;
327
global_unprotect = 1'b0;
328
SPRL_val         = 1'b0;
329
lock             = 1'b0;
330
unlock           = 1'b0;
331
dummy            = 0;
332
 
333
deep_power_down = 1'b0;
334
status_read     = 1'b0;
335
erasing_block4  = 1'b0;
336
erasing_block32 = 1'b0;
337
erasing_block64 = 1'b0;
338
erasing_chip    = 1'b0;
339
rd_dummy        = 1'b0;
340
byte_prog       = 1'b0;
341
seq_byte_prog   = 1'b0;
342
seq_byte_start  = 1'b0;
343
 
344
end // end of initial
345
 
346
// ********************** Drive SO ********************* //
347
bufif1 (SO, SO_reg, SO_on); //SO will be driven only if SO_on is High
348
 
349
// global protection and unprotection on sectors
350
always@(global_protect or global_unprotect)
351
begin
352
        if(global_protect==1'b1)
353
                sector_reg = 64'hFFFFFFFFFFFFFFFF;
354
        else if(global_unprotect==1'b1)
355
                sector_reg[SECTOR-1:0] = 'b0;
356
end
357
 
358
// ********************* Status register ********************* //
359
always @(WPB or lock or unlock) //SPRL bit locking & Unlocking
360
begin
361
        if(WPB==1'b1 && SPRL==1'b0 && lock==1'b1)
362
                SPRL = 1'b1;
363
        else if(WPB==1'b1 && SPRL==1'b1 && unlock==1'b1)
364
                SPRL = 1'b0; // S/W Locked
365
        else if(WPB==1'b0 && SPRL==1'b0 && lock==1'b1)
366
                SPRL = 1'b1;
367
        else if(WPB==1'b0 && SPRL==1'b1 && unlock==1'b1)
368
                SPRL = 1'b1; // H/W Locked
369
end
370
 
371
always @(WPB)                   // Write Protect (WP!) Pin Status
372
begin
373
        WPP = WPB;
374
end
375
 
376
always @(sector_reg)            // Software Protection Status
377
begin
378
        if(sector_reg[SECTOR-1:0]=='d0)
379
                SWP = 2'b00;
380
        else if((|sector_reg==1'b1) && (&sector_reg==1'b0))
381
                SWP = 2'b01;
382
        else if(&sector_reg==1'b1)
383
                SWP = 2'b11;
384
end
385
 
386
always @(SPRL or SPM or EPE or WPP or SWP or WEL or RDYnBSY)
387
begin
388
        status_reg = {SPRL,SPM,EPE,WPP,SWP,WEL,RDYnBSY};
389
end
390
 
391
// ******* to receive opcode and to switch to respective blocks ******* //
392
always @(negedge CSB)  // the device will now become active
393
begin : get_opcode_
394
 
395
        //@(negedge SCK);
396
        get_opcode;  // get opcode here
397
 
398
        if (deep_power_down == 1'b1) // Can be only after background has been enabled
399
                case (read_data)
400
                        8'hAB:  // Resume from Deep Power-down
401
                        begin
402
                                $display("Opcode(%h) for Resume from Deep Power-down received",read_data);
403
                                -> RDPD;
404
                        end
405
                        default :
406
                        begin
407
                                $display ("Opcode %h is not allowed: device in Deep Power-down", read_data);
408
                                disable get_opcode_;
409
                        end
410
                endcase
411
        else
412
        begin
413
                case (read_data)        // based on opcode, trigger an action
414
                8'h0B : // Read Array
415
                        begin
416
                                $display("Opcode(%h) for Read Array received",read_data);
417
                                rd_dummy = 1'b1;
418
                                -> RA;
419
                        end
420
                8'h03 : // Read Array (low freq)
421
                  begin
422
                     // Comment out this to clean up sim output
423
                     //$display("Opcode(%h) for Read Array (Low Freq) received",read_data);
424
                     rd_dummy = 1'b0;
425
                     -> RA;
426
                        end
427
                8'h20 : // Block erase 4 KB
428
                        begin
429
                                $display("Opcode(%h) for 4 KB Block erase received",read_data);
430
                                -> BE4;
431
                        end
432
                8'h52 : // Block erase 32 KB
433
                        begin
434
                                $display("Opcode(%h) for 32 KB Block erase received",read_data);
435
                                -> BE32;
436
                        end
437
                8'hD8 : // Block erase 64 KB
438
                        begin
439
                                $display("Opcode(%h) for 64 KB Block erase received",read_data);
440
                                -> BE64;
441
                        end
442
                8'h60 : // Chip erase
443
                        begin
444
                                $display("Opcode(%h) for Chip erase received",read_data);
445
                                -> CE;
446
                        end
447
                8'hC7 : // Chip erase
448
                        begin
449
                                $display("Opcode(%h) for Chip erase received",read_data);
450
                                -> CE;
451
                        end
452
                8'h02 : // Byte Program
453
                        begin
454
                                $display("Opcode(%h) Byte Program received",read_data);
455
                                -> BP;
456
                        end
457
                8'hAD : // Sequential Byte Program Mode Erase
458
                        begin
459
                                if(DEVICE=="AT25DF041A" || DEVICE=="AT26DF081A" || DEVICE=="AT26DF161A")
460
                                begin
461
                                        $display("Opcode(%h) Sequential Byte Program received",read_data);
462
                                        -> SBP;
463
                                end
464
                                else if(DEVICE=="AT26DF321")
465
                                        $display("Sequential Byte Program is not supported for device %s",DEVICE);
466
                        end
467
                8'hAF : // Sequential Byte Program Mode
468
                        begin
469
                                if(DEVICE=="AT25DF041A" || DEVICE=="AT26DF081A" || DEVICE=="AT26DF161A")
470
                                begin
471
                                        $display("Opcode(%h) Sequential Byte Program received",read_data);
472
                                        -> SBP;
473
                                end
474
                                else if(DEVICE=="AT26DF321")
475
                                        $display("Sequential Byte Program is not supported for device %s",DEVICE);
476
                        end
477
                8'h06 : // Write Enable
478
                        begin
479
                                $display("Opcode(%h) for Write Enable received",read_data);
480
                                -> WE;
481
                        end
482
                8'h04 : // Write Disable
483
                        begin
484
                                $display("Opcode(%h) for Write Disable received",read_data);
485
                                -> WD;
486
                        end
487
                8'h36 : // Protect Sector
488
                        begin
489
                                $display("Opcode(%h) for Protect Sector received",read_data);
490
                                -> PS;
491
                        end
492
                8'h39 : // Unprotect Sector
493
                        begin
494
                                $display("Opcode(%h) for Unprotect Sector received",read_data);
495
                                -> UPS;
496
                        end
497
                8'h3C : // Read Sector Protection Register
498
                        begin
499
                                $display("Opcode(%h) for Read Sector Protection Register received",read_data);
500
                                -> RSPR;
501
                        end
502
                8'h05 : // Read Status Register
503
                        begin
504
                                $display("Opcode(%h) for Status Register Read received",read_data);
505
                                -> RSR;
506
                        end
507
                8'h01 : // Write Status Register
508
                        begin
509
                                $display("Opcode(%h) for Write Status Register received",read_data);
510
                                -> WSR;
511
                        end
512
                8'h9F : // Read Manufacturer and Device ID
513
                        begin
514
                                $display("Opcode(%h) for Read Manufacturer and Device ID received",read_data);
515
                                -> MIR;
516
                        end
517
                8'hB9 : // Deep Power-down
518
                        begin
519
                                $display("Opcode(%h) for Deep Power-down received",read_data);
520
                                -> EDPD;
521
                        end
522
                default :
523
                begin
524
                        $display ("Unrecognized opcode %h", read_data);
525
                        disable get_opcode_;
526
                end
527
                endcase
528
        end
529
end
530
 
531
// *********************** TASKS / FUNCTIONS ************************** //
532
 
533
// get_opcode is a task to get 8 bits of opcode.
534
// It obtains 8 bits of data obtained on SI
535
task get_opcode;
536
 
537
integer i;
538
begin
539
        for (i=8; i>0; i = i-1)
540
        begin
541
                @(posedge SCK);
542
                read_data[i-1] = SI;
543
                if(HOLDB==1'b0)
544
                        wait (HOLDB);
545
        end
546
        i=7;
547
end
548
endtask
549
 
550
// get_data is a task to get 8 bits of data. This data could be an address,
551
// data or anything. It just obtains 8 bits of data obtained on SI
552
task get_data;
553
 
554
integer i;
555
begin
556
        for (i=7; i>=0; i = i-1)
557
        begin
558
                @(posedge SCK);
559
                read_data[i] = SI;
560
                if(HOLDB==1'b0)
561
                        wait (HOLDB);
562
        end
563
        i=7;
564
end
565
endtask
566
 
567
// task read_out_array is to read from main Memory
568
task read_out_array ;
569
input [23:0] read_addr;
570
integer i;
571
 
572
begin
573
        temp_data = memory [read_addr];
574
        i = 7;
575
        while (CSB == 1'b0) // continue transmitting, while, CSB is Low
576
        begin
577
                @(negedge SCK);
578
                SO_reg = 1'bx;
579
                if(HOLDB==1'b0)
580
                begin
581
                        #tHLQZ SO_on = 1'b0;
582
                        wait (HOLDB);
583
                        #tHHQX;
584
                end
585
                #tV SO_reg = temp_data[i];
586
                SO_on = 1'b1;
587
                if (i == 0)
588 403 julius
                  begin
589
                     if (VERBOSE)
590
                        $display ("Data: %h read from memory location %h",temp_data,read_addr);
591 6 julius
                        read_addr = read_addr + 1; // next byte
592
                        i = 7;
593
                        if (read_addr >= (MEMSIZE-1))
594
                                read_addr = 0; // Note that rollover occurs at end of memory,
595
                        temp_data = memory [read_addr];
596
                end
597
                else
598
                        i = i - 1; // next bit
599
        end // reading over, because CSB has gone high
600
end
601
endtask
602
 
603
// Sector protection
604
task protect_sector;
605
input [23:0] protect_address;
606
 
607
begin
608
        $display("Entered Protect Sector task");
609
 
610
    if (DEVICE == "AT26DF321" && protect==1'b1)
611
    begin
612
        if(protect_address[23:16]==8'b00111111)
613
                sector_reg[63] = 1'b1;
614
        else if(protect_address[23:16]==8'b00111110)
615
                sector_reg[62] = 1'b1;
616
        else if(protect_address[23:16]==8'b00111101)
617
                sector_reg[61] = 1'b1;
618
        else if(protect_address[23:16]==8'b00111100)
619
                sector_reg[60] = 1'b1;
620
        else if(protect_address[23:16]==8'b00111011)
621
                sector_reg[59] = 1'b1;
622
        else if(protect_address[23:16]==8'b00111010)
623
                sector_reg[58] = 1'b1;
624
        else if(protect_address[23:16]==8'b00111001)
625
                sector_reg[57] = 1'b1;
626
        else if(protect_address[23:16]==8'b00111000)
627
                sector_reg[56] = 1'b1;
628
        else if(protect_address[23:16]==8'b00110111)
629
                sector_reg[55] = 1'b1;
630
        else if(protect_address[23:16]==8'b00110110)
631
                sector_reg[54] = 1'b1;
632
        else if(protect_address[23:16]==8'b00110101)
633
                sector_reg[53] = 1'b1;
634
        else if(protect_address[23:16]==8'b00110100)
635
                sector_reg[52] = 1'b1;
636
        else if(protect_address[23:16]==8'b00110011)
637
                sector_reg[51] = 1'b1;
638
        else if(protect_address[23:16]==8'b00110010)
639
                sector_reg[50] = 1'b1;
640
        else if(protect_address[23:16]==8'b00110001)
641
                sector_reg[49] = 1'b1;
642
        else if(protect_address[23:16]==8'b00110000)
643
                sector_reg[48] = 1'b1;
644
        else if(protect_address[23:16]==8'b00101111)
645
                sector_reg[47] = 1'b1;
646
        else if(protect_address[23:16]==8'b00101110)
647
                sector_reg[46] = 1'b1;
648
        else if(protect_address[23:16]==8'b00101101)
649
                sector_reg[45] = 1'b1;
650
        else if(protect_address[23:16]==8'b00101100)
651
                sector_reg[44] = 1'b1;
652
        else if(protect_address[23:16]==8'b00101011)
653
                sector_reg[43] = 1'b1;
654
        else if(protect_address[23:16]==8'b00101010)
655
                sector_reg[42] = 1'b1;
656
        else if(protect_address[23:16]==8'b00101001)
657
                sector_reg[41] = 1'b1;
658
        else if(protect_address[23:16]==8'b00101000)
659
                sector_reg[40] = 1'b1;
660
        else if(protect_address[23:16]==8'b00100111)
661
                sector_reg[39] = 1'b1;
662
        else if(protect_address[23:16]==8'b00100110)
663
                sector_reg[38] = 1'b1;
664
        else if(protect_address[23:16]==8'b00100101)
665
                sector_reg[37] = 1'b1;
666
        else if(protect_address[23:16]==8'b00100100)
667
                sector_reg[36] = 1'b1;
668
        else if(protect_address[23:16]==8'b00100011)
669
                sector_reg[35] = 1'b1;
670
        else if(protect_address[23:16]==8'b00100010)
671
                sector_reg[34] = 1'b1;
672
        else if(protect_address[23:16]==8'b00100001)
673
                sector_reg[33] = 1'b1;
674
        else if(protect_address[23:16]==8'b00100000)
675
                sector_reg[32] = 1'b1;
676
    end
677
    if ((DEVICE == "AT26DF161A" || DEVICE == "AT26DF321") && protect==1'b1)
678
    begin
679
        if(protect_address[23:16]==8'b00011111)
680
                sector_reg[31] = 1'b1;
681
        else if(protect_address[23:16]==8'b00011110)
682
                sector_reg[30] = 1'b1;
683
        else if(protect_address[23:16]==8'b00011101)
684
                sector_reg[29] = 1'b1;
685
        else if(protect_address[23:16]==8'b00011100)
686
                sector_reg[28] = 1'b1;
687
        else if(protect_address[23:16]==8'b00011011)
688
                sector_reg[27] = 1'b1;
689
        else if(protect_address[23:16]==8'b00011010)
690
                sector_reg[26] = 1'b1;
691
        else if(protect_address[23:16]==8'b00011001)
692
                sector_reg[25] = 1'b1;
693
        else if(protect_address[23:16]==8'b00011000)
694
                sector_reg[24] = 1'b1;
695
        else if(protect_address[23:16]==8'b00010111)
696
                sector_reg[23] = 1'b1;
697
        else if(protect_address[23:16]==8'b00010110)
698
                sector_reg[22] = 1'b1;
699
        else if(protect_address[23:16]==8'b00010101)
700
                sector_reg[21] = 1'b1;
701
        else if(protect_address[23:16]==8'b00010100)
702
                sector_reg[20] = 1'b1;
703
        else if(protect_address[23:16]==8'b00010011)
704
                sector_reg[19] = 1'b1;
705
        else if(protect_address[23:16]==8'b00010010)
706
                sector_reg[18] = 1'b1;
707
        else if(protect_address[23:16]==8'b00010001)
708
                sector_reg[17] = 1'b1;
709
        else if(protect_address[23:16]==8'b00010000)
710
                sector_reg[16] = 1'b1;
711
    end
712
 
713
    if (DEVICE == "AT26DF081A" && protect==1'b1) // un-uniform sectors of AT26DF081A
714
    begin
715
        if(protect_address[23:14]==10'b00001111_00)
716
                sector_reg[15] = 1'b1;
717
        else if(protect_address[23:13]==11'b00001111_010)
718
                sector_reg[16] = 1'b1;
719
        else if(protect_address[23:13]==11'b00001111_011)
720
                sector_reg[17] = 1'b1;
721
        else if(protect_address[23:17]==9'b00001111_1)
722
                sector_reg[18] = 1'b1;
723
    end
724
    else if ((DEVICE == "AT26DF161A" || DEVICE == "AT26DF321") && protect==1'b1)
725
    begin
726
        if(protect_address[23:16]==8'b00001111)
727
                sector_reg[15] = 1'b1;
728
    end
729
 
730
    if ((DEVICE == "AT26DF081A" || DEVICE == "AT26DF161A" || DEVICE == "AT26DF321") && protect==1'b1)
731
    begin
732
//      if(protect_address[23:16]==8'b00001111)
733
//              sector_reg[15] = 1'b1;
734
        if(protect_address[23:16]==8'b00001110)
735
                sector_reg[14] = 1'b1;
736
        else if(protect_address[23:16]==8'b00001101)
737
                sector_reg[13] = 1'b1;
738
        else if(protect_address[23:16]==8'b00001100)
739
                sector_reg[12] = 1'b1;
740
        else if(protect_address[23:16]==8'b00001011)
741
                sector_reg[11] = 1'b1;
742
        else if(protect_address[23:16]==8'b00001010)
743
                sector_reg[10] = 1'b1;
744
        else if(protect_address[23:16]==8'b00001001)
745
                sector_reg[9] = 1'b1;
746
        else if(protect_address[23:16]==8'b00001000)
747
                sector_reg[8] = 1'b1;
748
    end
749
 
750
    if (DEVICE == "AT25DF041A" && protect==1'b1) // un-uniform sectors of AT25DF041A
751
    begin
752
        if(protect_address[23:15]==9'b00000111_0)
753
                sector_reg[7] = 1'b1;
754
        else if(protect_address[23:13]==11'b00000111_100)
755
                sector_reg[8] = 1'b1;
756
        else if(protect_address[23:13]==11'b00000111_101)
757
                sector_reg[9] = 1'b1;
758
        else if(protect_address[23:14]==10'b00000111_11)
759
                sector_reg[10] = 1'b1;
760
    end
761
    else if ((DEVICE == "AT26DF081A" || DEVICE == "AT26DF161A" || DEVICE == "AT26DF321") && protect==1'b1)
762
        if(protect_address[23:16]==8'b00000111)
763
                sector_reg[7] = 1'b1;
764
 
765
    if ((DEVICE == "AT25DF041A" || DEVICE == "AT26DF081A"
766
        || DEVICE == "AT26DF161A" || DEVICE == "AT26DF321") && protect==1'b1)
767
    begin
768
//      if(protect_address[23:16]==8'b00000111)
769
//              sector_reg[7] = 1'b1;
770
        if(protect_address[23:16]==8'b00000110)
771
                sector_reg[6] = 1'b1;
772
        else if(protect_address[23:16]==8'b00000101)
773
                sector_reg[5] = 1'b1;
774
        else if(protect_address[23:16]==8'b00000100)
775
                sector_reg[4] = 1'b1;
776
        else if(protect_address[23:16]==8'b00000011)
777
                sector_reg[3] = 1'b1;
778
        else if(protect_address[23:16]==8'b00000010)
779
                sector_reg[2] = 1'b1;
780
        else if(protect_address[23:16]==8'b00000001)
781
                sector_reg[1] = 1'b1;
782
        else if(protect_address[23:16]==8'b00000000)
783
                sector_reg[0] = 1'b1;
784
    end
785
end
786
endtask
787
 
788
// Sector Unprotection
789
task unprotect_sector;
790
input [23:0] unprotect_address;
791
begin
792
    if ((DEVICE == "AT25DF041A") && unprotect==1'b1) // sectors of AT25DF041A
793
    begin
794
        $display("Entered Unprotect sector for Device: AT25DF041A");
795
        if(unprotect_address[23:14]==10'b00000111_11)
796
                sector_reg[10] = 1'b0;
797
        else if(unprotect_address[23:13]==11'b00000111_101)
798
                sector_reg[9] = 1'b0;
799
        else if(unprotect_address[23:13]==11'b00000111_100)
800
                sector_reg[8] = 1'b0;
801
        else if(unprotect_address[23:15]==9'b00000111_0)
802
                sector_reg[7] = 1'b0;
803
        else if(unprotect_address[23:16]==8'b00000110)
804
                sector_reg[6] = 1'b0;
805
        else if(unprotect_address[23:16]==8'b00000101)
806
                sector_reg[5] = 1'b0;
807
        else if(unprotect_address[23:16]==8'b00000100)
808
                sector_reg[4] = 1'b0;
809
        else if(unprotect_address[23:16]==8'b00000011)
810
                sector_reg[3] = 1'b0;
811
        else if(unprotect_address[23:16]==8'b00000010)
812
                sector_reg[2] = 1'b0;
813
        else if(unprotect_address[23:16]==8'b00000001)
814
                sector_reg[1] = 1'b0;
815
        else if(unprotect_address[23:16]==8'b00000000)
816
                sector_reg[0] = 1'b0;
817
    end
818
    else if (DEVICE == "AT26DF081A" && unprotect==1'b1) // sectors of AT26DF081A
819
    begin
820
        $display("Entered Unprotect sector for Device: AT26DF081A");
821
        if(unprotect_address[23:17]==9'b00001111_1)
822
                sector_reg[18] = 1'b0;
823
        else if(unprotect_address[23:13]==11'b00001111_011)
824
                sector_reg[17] = 1'b0;
825
        else if(unprotect_address[23:13]==11'b00001111_010)
826
                sector_reg[16] = 1'b0;
827
        else if(unprotect_address[23:14]==10'b00001111_00)
828
                sector_reg[15] = 1'b0;
829
        else if(unprotect_address[23:16]==8'b00001110)
830
                sector_reg[14] = 1'b0;
831
        else if(unprotect_address[23:16]==8'b00001101)
832
                sector_reg[13] = 1'b0;
833
        else if(unprotect_address[23:16]==8'b00001100)
834
                sector_reg[12] = 1'b0;
835
        else if(unprotect_address[23:16]==8'b00001011)
836
                sector_reg[11] = 1'b0;
837
        else if(unprotect_address[23:16]==8'b00001010)
838
                sector_reg[10] = 1'b0;
839
        else if(unprotect_address[23:16]==8'b00001001)
840
                sector_reg[9] = 1'b0;
841
        else if(unprotect_address[23:16]==8'b00001000)
842
                sector_reg[8] = 1'b0;
843
        else if(unprotect_address[23:16]==8'b00000111)
844
                sector_reg[7] = 1'b0;
845
        else if(unprotect_address[23:16]==8'b00000110)
846
                sector_reg[6] = 1'b0;
847
        else if(unprotect_address[23:16]==8'b00000101)
848
                sector_reg[5] = 1'b0;
849
        else if(unprotect_address[23:16]==8'b00000100)
850
                sector_reg[4] = 1'b0;
851
        else if(unprotect_address[23:16]==8'b00000011)
852
                sector_reg[3] = 1'b0;
853
        else if(unprotect_address[23:16]==8'b00000010)
854
                sector_reg[2] = 1'b0;
855
        else if(unprotect_address[23:16]==8'b00000001)
856
                sector_reg[1] = 1'b0;
857
        else if(unprotect_address[23:16]==8'b00000000)
858
                sector_reg[0] = 1'b0;
859
    end
860
    else if ((DEVICE == "AT26DF161A") && unprotect==1'b1) // sectors of AT26DF161A
861
    begin
862
        $display("Entered Unprotect sector for Device: AT26DF161A");
863
        if(unprotect_address[23:16]==8'b00011111)
864
                sector_reg[31] = 1'b0;
865
        else if(unprotect_address[23:16]==8'b00011110)
866
                sector_reg[30] = 1'b0;
867
        else if(unprotect_address[23:16]==8'b00011101)
868
                sector_reg[29] = 1'b0;
869
        else if(unprotect_address[23:16]==8'b00011100)
870
                sector_reg[28] = 1'b0;
871
        else if(unprotect_address[23:16]==8'b00011011)
872
                sector_reg[27] = 1'b0;
873
        else if(unprotect_address[23:16]==8'b00011010)
874
                sector_reg[26] = 1'b0;
875
        else if(unprotect_address[23:16]==8'b00011001)
876
                sector_reg[25] = 1'b0;
877
        else if(unprotect_address[23:16]==8'b00011000)
878
                sector_reg[24] = 1'b0;
879
        else if(unprotect_address[23:16]==8'b00010111)
880
                sector_reg[23] = 1'b0;
881
        else if(unprotect_address[23:16]==8'b00010110)
882
                sector_reg[22] = 1'b0;
883
        else if(unprotect_address[23:16]==8'b00010101)
884
                sector_reg[21] = 1'b0;
885
        else if(unprotect_address[23:16]==8'b00010100)
886
                sector_reg[20] = 1'b0;
887
        else if(unprotect_address[23:16]==8'b00010011)
888
                sector_reg[19] = 1'b0;
889
        else if(unprotect_address[23:16]==8'b00010010)
890
                sector_reg[18] = 1'b0;
891
        else if(unprotect_address[23:16]==8'b00010001)
892
                sector_reg[17] = 1'b0;
893
        else if(unprotect_address[23:16]==8'b00010000)
894
                sector_reg[16] = 1'b0;
895
        else if(unprotect_address[23:16]==8'b00001111)
896
                sector_reg[15] = 1'b0;
897
        else if(unprotect_address[23:16]==8'b00001110)
898
                sector_reg[14] = 1'b0;
899
        else if(unprotect_address[23:16]==8'b00001101)
900
                sector_reg[13] = 1'b0;
901
        else if(unprotect_address[23:16]==8'b00001100)
902
                sector_reg[12] = 1'b0;
903
        else if(unprotect_address[23:16]==8'b00001011)
904
                sector_reg[11] = 1'b0;
905
        else if(unprotect_address[23:16]==8'b00001010)
906
                sector_reg[10] = 1'b0;
907
        else if(unprotect_address[23:16]==8'b00001001)
908
                sector_reg[9] = 1'b0;
909
        else if(unprotect_address[23:16]==8'b00001000)
910
                sector_reg[8] = 1'b0;
911
        else if(unprotect_address[23:16]==8'b00000111)
912
                sector_reg[7] = 1'b0;
913
        else if(unprotect_address[23:16]==8'b00000110)
914
                sector_reg[6] = 1'b0;
915
        else if(unprotect_address[23:16]==8'b00000101)
916
                sector_reg[5] = 1'b0;
917
        else if(unprotect_address[23:16]==8'b00000100)
918
                sector_reg[4] = 1'b0;
919
        else if(unprotect_address[23:16]==8'b00000011)
920
                sector_reg[3] = 1'b0;
921
        else if(unprotect_address[23:16]==8'b00000010)
922
                sector_reg[2] = 1'b0;
923
        else if(unprotect_address[23:16]==8'b00000001)
924
                sector_reg[1] = 1'b0;
925
        else if(unprotect_address[23:16]==8'b00000000)
926
                sector_reg[0] = 1'b0;
927
    end
928
    else if (DEVICE == "AT26DF321" && unprotect==1'b1) // sectors of AT26DF321
929
    begin
930
        $display("Entered Unprotect sector for Device: AT26DF321");
931
        if(unprotect_address[23:16]==8'b00111111)
932
                sector_reg[63] = 1'b0;
933
        else if(unprotect_address[23:16]==8'b00111110)
934
                sector_reg[62] = 1'b0;
935
        else if(unprotect_address[23:16]==8'b00111101)
936
                sector_reg[61] = 1'b0;
937
        else if(unprotect_address[23:16]==8'b00111100)
938
                sector_reg[60] = 1'b0;
939
        else if(unprotect_address[23:16]==8'b00111011)
940
                sector_reg[59] = 1'b0;
941
        else if(unprotect_address[23:16]==8'b00111010)
942
                sector_reg[58] = 1'b0;
943
        else if(unprotect_address[23:16]==8'b00111001)
944
                sector_reg[57] = 1'b0;
945
        else if(unprotect_address[23:16]==8'b00111000)
946
                sector_reg[56] = 1'b0;
947
        else if(unprotect_address[23:16]==8'b00110111)
948
                sector_reg[55] = 1'b0;
949
        else if(unprotect_address[23:16]==8'b00110110)
950
                sector_reg[54] = 1'b0;
951
        else if(unprotect_address[23:16]==8'b00110101)
952
                sector_reg[53] = 1'b0;
953
        else if(unprotect_address[23:16]==8'b00110100)
954
                sector_reg[52] = 1'b0;
955
        else if(unprotect_address[23:16]==8'b00110011)
956
                sector_reg[51] = 1'b0;
957
        else if(unprotect_address[23:16]==8'b00110010)
958
                sector_reg[50] = 1'b0;
959
        else if(unprotect_address[23:16]==8'b00110001)
960
                sector_reg[49] = 1'b0;
961
        else if(unprotect_address[23:16]==8'b00110000)
962
                sector_reg[48] = 1'b0;
963
        else if(unprotect_address[23:16]==8'b00101111)
964
                sector_reg[47] = 1'b0;
965
        else if(unprotect_address[23:16]==8'b00101110)
966
                sector_reg[46] = 1'b0;
967
        else if(unprotect_address[23:16]==8'b00101101)
968
                sector_reg[45] = 1'b0;
969
        else if(unprotect_address[23:16]==8'b00101100)
970
                sector_reg[44] = 1'b0;
971
        else if(unprotect_address[23:16]==8'b00101011)
972
                sector_reg[43] = 1'b0;
973
        else if(unprotect_address[23:16]==8'b00101010)
974
                sector_reg[42] = 1'b0;
975
        else if(unprotect_address[23:16]==8'b00101001)
976
                sector_reg[41] = 1'b0;
977
        else if(unprotect_address[23:16]==8'b00101000)
978
                sector_reg[40] = 1'b0;
979
        else if(unprotect_address[23:16]==8'b00100111)
980
                sector_reg[39] = 1'b0;
981
        else if(unprotect_address[23:16]==8'b00100110)
982
                sector_reg[38] = 1'b0;
983
        else if(unprotect_address[23:16]==8'b00100101)
984
                sector_reg[37] = 1'b0;
985
        else if(unprotect_address[23:16]==8'b00100100)
986
                sector_reg[36] = 1'b0;
987
        else if(unprotect_address[23:16]==8'b00100011)
988
                sector_reg[35] = 1'b0;
989
        else if(unprotect_address[23:16]==8'b00100010)
990
                sector_reg[34] = 1'b0;
991
        else if(unprotect_address[23:16]==8'b00100001)
992
                sector_reg[33] = 1'b0;
993
        else if(unprotect_address[23:16]==8'b00100000)
994
                sector_reg[32] = 1'b0;
995
        else if(unprotect_address[23:16]==8'b00011111)
996
                sector_reg[31] = 1'b0;
997
        else if(unprotect_address[23:16]==8'b00011110)
998
                sector_reg[30] = 1'b0;
999
        else if(unprotect_address[23:16]==8'b00011101)
1000
                sector_reg[29] = 1'b0;
1001
        else if(unprotect_address[23:16]==8'b00011100)
1002
                sector_reg[28] = 1'b0;
1003
        else if(unprotect_address[23:16]==8'b00011011)
1004
                sector_reg[27] = 1'b0;
1005
        else if(unprotect_address[23:16]==8'b00011010)
1006
                sector_reg[26] = 1'b0;
1007
        else if(unprotect_address[23:16]==8'b00011001)
1008
                sector_reg[25] = 1'b0;
1009
        else if(unprotect_address[23:16]==8'b00011000)
1010
                sector_reg[24] = 1'b0;
1011
        else if(unprotect_address[23:16]==8'b00010111)
1012
                sector_reg[23] = 1'b0;
1013
        else if(unprotect_address[23:16]==8'b00010110)
1014
                sector_reg[22] = 1'b0;
1015
        else if(unprotect_address[23:16]==8'b00010101)
1016
                sector_reg[21] = 1'b0;
1017
        else if(unprotect_address[23:16]==8'b00010100)
1018
                sector_reg[20] = 1'b0;
1019
        else if(unprotect_address[23:16]==8'b00010011)
1020
                sector_reg[19] = 1'b0;
1021
        else if(unprotect_address[23:16]==8'b00010010)
1022
                sector_reg[18] = 1'b0;
1023
        else if(unprotect_address[23:16]==8'b00010001)
1024
                sector_reg[17] = 1'b0;
1025
        else if(unprotect_address[23:16]==8'b00010000)
1026
                sector_reg[16] = 1'b0;
1027
        else if(unprotect_address[23:16]==8'b00001111)
1028
                sector_reg[15] = 1'b0;
1029
        else if(unprotect_address[23:16]==8'b00001110)
1030
                sector_reg[14] = 1'b0;
1031
        else if(unprotect_address[23:16]==8'b00001101)
1032
                sector_reg[13] = 1'b0;
1033
        else if(unprotect_address[23:16]==8'b00001100)
1034
                sector_reg[12] = 1'b0;
1035
        else if(unprotect_address[23:16]==8'b00001011)
1036
                sector_reg[11] = 1'b0;
1037
        else if(unprotect_address[23:16]==8'b00001010)
1038
                sector_reg[10] = 1'b0;
1039
        else if(unprotect_address[23:16]==8'b00001001)
1040
                sector_reg[9] = 1'b0;
1041
        else if(unprotect_address[23:16]==8'b00001000)
1042
                sector_reg[8] = 1'b0;
1043
        else if(unprotect_address[23:16]==8'b00000111)
1044
                sector_reg[7] = 1'b0;
1045
        else if(unprotect_address[23:16]==8'b00000110)
1046
                sector_reg[6] = 1'b0;
1047
        else if(unprotect_address[23:16]==8'b00000101)
1048
                sector_reg[5] = 1'b0;
1049
        else if(unprotect_address[23:16]==8'b00000100)
1050
                sector_reg[4] = 1'b0;
1051
        else if(unprotect_address[23:16]==8'b00000011)
1052
                sector_reg[3] = 1'b0;
1053
        else if(unprotect_address[23:16]==8'b00000010)
1054
                sector_reg[2] = 1'b0;
1055
        else if(unprotect_address[23:16]==8'b00000001)
1056
                sector_reg[1] = 1'b0;
1057
        else if(unprotect_address[23:16]==8'b00000000)
1058
                sector_reg[0] = 1'b0;
1059
    end
1060
        else
1061
        $display("Unprotect Sector failed");
1062
 
1063
end
1064
endtask
1065
 
1066
// Check Sector Protection
1067
task check_protection;
1068
input [23:0] check_address;
1069
begin
1070
    if (DEVICE == "AT26DF321")
1071
    begin
1072
        if((check_address[23:16]==8'b00111111 && sector_reg[63]==1'b1)
1073
        || (check_address[23:16]==8'b00111110 && sector_reg[62]==1'b1)
1074
        || (check_address[23:16]==8'b00111101 && sector_reg[61]==1'b1)
1075
        || (check_address[23:16]==8'b00111100 && sector_reg[60]==1'b1)
1076
        || (check_address[23:16]==8'b00111011 && sector_reg[59]==1'b1)
1077
        || (check_address[23:16]==8'b00111010 && sector_reg[58]==1'b1)
1078
        || (check_address[23:16]==8'b00111001 && sector_reg[57]==1'b1)
1079
        || (check_address[23:16]==8'b00111000 && sector_reg[56]==1'b1)
1080
        || (check_address[23:16]==8'b00110111 && sector_reg[55]==1'b1)
1081
        || (check_address[23:16]==8'b00110110 && sector_reg[54]==1'b1)
1082
        || (check_address[23:16]==8'b00110101 && sector_reg[53]==1'b1)
1083
        || (check_address[23:16]==8'b00110100 && sector_reg[52]==1'b1)
1084
        || (check_address[23:16]==8'b00110011 && sector_reg[51]==1'b1)
1085
        || (check_address[23:16]==8'b00110010 && sector_reg[50]==1'b1)
1086
        || (check_address[23:16]==8'b00110001 && sector_reg[49]==1'b1)
1087
        || (check_address[23:16]==8'b00110000 && sector_reg[48]==1'b1)
1088
        || (check_address[23:16]==8'b00101111 && sector_reg[47]==1'b1)
1089
        || (check_address[23:16]==8'b00101110 && sector_reg[46]==1'b1)
1090
        || (check_address[23:16]==8'b00101101 && sector_reg[45]==1'b1)
1091
        || (check_address[23:16]==8'b00101100 && sector_reg[44]==1'b1)
1092
        || (check_address[23:16]==8'b00101011 && sector_reg[43]==1'b1)
1093
        || (check_address[23:16]==8'b00101010 && sector_reg[42]==1'b1)
1094
        || (check_address[23:16]==8'b00101001 && sector_reg[41]==1'b1)
1095
        || (check_address[23:16]==8'b00101000 && sector_reg[40]==1'b1)
1096
        || (check_address[23:16]==8'b00100111 && sector_reg[39]==1'b1)
1097
        || (check_address[23:16]==8'b00100110 && sector_reg[38]==1'b1)
1098
        || (check_address[23:16]==8'b00100101 && sector_reg[37]==1'b1)
1099
        || (check_address[23:16]==8'b00100100 && sector_reg[36]==1'b1)
1100
        || (check_address[23:16]==8'b00100011 && sector_reg[35]==1'b1)
1101
        || (check_address[23:16]==8'b00100010 && sector_reg[34]==1'b1)
1102
        || (check_address[23:16]==8'b00100001 && sector_reg[33]==1'b1)
1103
        || (check_address[23:16]==8'b00100000 && sector_reg[32]==1'b1)
1104
        || (check_address[23:16]==8'b00011111 && sector_reg[31]==1'b1)
1105
        || (check_address[23:16]==8'b00011110 && sector_reg[30]==1'b1)
1106
        || (check_address[23:16]==8'b00011101 && sector_reg[29]==1'b1)
1107
        || (check_address[23:16]==8'b00011100 && sector_reg[28]==1'b1)
1108
        || (check_address[23:16]==8'b00011011 && sector_reg[27]==1'b1)
1109
        || (check_address[23:16]==8'b00011010 && sector_reg[26]==1'b1)
1110
        || (check_address[23:16]==8'b00011001 && sector_reg[25]==1'b1)
1111
        || (check_address[23:16]==8'b00011000 && sector_reg[24]==1'b1)
1112
        || (check_address[23:16]==8'b00010111 && sector_reg[23]==1'b1)
1113
        || (check_address[23:16]==8'b00010110 && sector_reg[22]==1'b1)
1114
        || (check_address[23:16]==8'b00010101 && sector_reg[21]==1'b1)
1115
        || (check_address[23:16]==8'b00010100 && sector_reg[20]==1'b1)
1116
        || (check_address[23:16]==8'b00010011 && sector_reg[19]==1'b1)
1117
        || (check_address[23:16]==8'b00010010 && sector_reg[18]==1'b1)
1118
        || (check_address[23:16]==8'b00010001 && sector_reg[17]==1'b1)
1119
        || (check_address[23:16]==8'b00010000 && sector_reg[16]==1'b1)
1120
        || (check_address[23:16]==8'b00001111 && sector_reg[15]==1'b1)
1121
        || (check_address[23:16]==8'b00001110 && sector_reg[14]==1'b1)
1122
        || (check_address[23:16]==8'b00001101 && sector_reg[13]==1'b1)
1123
        || (check_address[23:16]==8'b00001100 && sector_reg[12]==1'b1)
1124
        || (check_address[23:16]==8'b00001011 && sector_reg[11]==1'b1)
1125
        || (check_address[23:16]==8'b00001010 && sector_reg[10]==1'b1)
1126
        || (check_address[23:16]==8'b00001001 && sector_reg[9] ==1'b1)
1127
        || (check_address[23:16]==8'b00001000 && sector_reg[8] ==1'b1)
1128
        || (check_address[23:16]==8'b00000111 && sector_reg[7] ==1'b1)
1129
        || (check_address[23:16]==8'b00000110 && sector_reg[6] ==1'b1)
1130
        || (check_address[23:16]==8'b00000101 && sector_reg[5] ==1'b1)
1131
        || (check_address[23:16]==8'b00000100 && sector_reg[4] ==1'b1)
1132
        || (check_address[23:16]==8'b00000011 && sector_reg[3] ==1'b1)
1133
        || (check_address[23:16]==8'b00000010 && sector_reg[2] ==1'b1)
1134
        || (check_address[23:16]==8'b00000001 && sector_reg[1] ==1'b1)
1135
        || (check_address[23:16]==8'b00000000 && sector_reg[0] ==1'b1))
1136
                protected = 1'b1;
1137
        else
1138
                protected = 1'b0;
1139
    end
1140
    else if (DEVICE == "AT26DF161A")
1141
    begin
1142
        if((check_address[23:16]==8'b00011111 && sector_reg[31]==1'b1)
1143
        || (check_address[23:16]==8'b00011110 && sector_reg[30]==1'b1)
1144
        || (check_address[23:16]==8'b00011101 && sector_reg[29]==1'b1)
1145
        || (check_address[23:16]==8'b00011100 && sector_reg[28]==1'b1)
1146
        || (check_address[23:16]==8'b00011011 && sector_reg[27]==1'b1)
1147
        || (check_address[23:16]==8'b00011010 && sector_reg[26]==1'b1)
1148
        || (check_address[23:16]==8'b00011001 && sector_reg[25]==1'b1)
1149
        || (check_address[23:16]==8'b00011000 && sector_reg[24]==1'b1)
1150
        || (check_address[23:16]==8'b00010111 && sector_reg[23]==1'b1)
1151
        || (check_address[23:16]==8'b00010110 && sector_reg[22]==1'b1)
1152
        || (check_address[23:16]==8'b00010101 && sector_reg[21]==1'b1)
1153
        || (check_address[23:16]==8'b00010100 && sector_reg[20]==1'b1)
1154
        || (check_address[23:16]==8'b00010011 && sector_reg[19]==1'b1)
1155
        || (check_address[23:16]==8'b00010010 && sector_reg[18]==1'b1)
1156
        || (check_address[23:16]==8'b00010001 && sector_reg[17]==1'b1)
1157
        || (check_address[23:16]==8'b00010000 && sector_reg[16]==1'b1)
1158
        || (check_address[23:16]==8'b00001111 && sector_reg[15]==1'b1)
1159
        || (check_address[23:16]==8'b00001110 && sector_reg[14]==1'b1)
1160
        || (check_address[23:16]==8'b00001101 && sector_reg[13]==1'b1)
1161
        || (check_address[23:16]==8'b00001100 && sector_reg[12]==1'b1)
1162
        || (check_address[23:16]==8'b00001011 && sector_reg[11]==1'b1)
1163
        || (check_address[23:16]==8'b00001010 && sector_reg[10]==1'b1)
1164
        || (check_address[23:16]==8'b00001001 && sector_reg[9] ==1'b1)
1165
        || (check_address[23:16]==8'b00001000 && sector_reg[8] ==1'b1)
1166
        || (check_address[23:16]==8'b00000111 && sector_reg[7] ==1'b1)
1167
        || (check_address[23:16]==8'b00000110 && sector_reg[6] ==1'b1)
1168
        || (check_address[23:16]==8'b00000101 && sector_reg[5] ==1'b1)
1169
        || (check_address[23:16]==8'b00000100 && sector_reg[4] ==1'b1)
1170
        || (check_address[23:16]==8'b00000011 && sector_reg[3] ==1'b1)
1171
        || (check_address[23:16]==8'b00000010 && sector_reg[2] ==1'b1)
1172
        || (check_address[23:16]==8'b00000001 && sector_reg[1] ==1'b1)
1173
        || (check_address[23:16]==8'b00000000 && sector_reg[0] ==1'b1))
1174
                protected = 1'b1;
1175
        else
1176
                protected = 1'b0;
1177
    end
1178
    else if (DEVICE == "AT26DF081A") // un-uniform sectors of AT26DF081A
1179
    begin
1180
        if((check_address[23:17]==9'b00001111_1 && sector_reg[18]   ==1'b1)
1181
        || (check_address[23:13]==11'b00001111_011 && sector_reg[17]==1'b1)
1182
        || (check_address[23:13]==11'b00001111_010 && sector_reg[16]==1'b1)
1183
        || (check_address[23:14]==10'b00001111_00 && sector_reg[15] ==1'b1)
1184
        || (check_address[23:16]==8'b00001110 && sector_reg[14]==1'b1)
1185
        || (check_address[23:16]==8'b00001101 && sector_reg[13]==1'b1)
1186
        || (check_address[23:16]==8'b00001100 && sector_reg[12]==1'b1)
1187
        || (check_address[23:16]==8'b00001011 && sector_reg[11]==1'b1)
1188
        || (check_address[23:16]==8'b00001010 && sector_reg[10]==1'b1)
1189
        || (check_address[23:16]==8'b00001001 && sector_reg[9] ==1'b1)
1190
        || (check_address[23:16]==8'b00001000 && sector_reg[8] ==1'b1)
1191
        || (check_address[23:16]==8'b00000111 && sector_reg[7] ==1'b1)
1192
        || (check_address[23:16]==8'b00000110 && sector_reg[6] ==1'b1)
1193
        || (check_address[23:16]==8'b00000101 && sector_reg[5] ==1'b1)
1194
        || (check_address[23:16]==8'b00000100 && sector_reg[4] ==1'b1)
1195
        || (check_address[23:16]==8'b00000011 && sector_reg[3] ==1'b1)
1196
        || (check_address[23:16]==8'b00000010 && sector_reg[2] ==1'b1)
1197
        || (check_address[23:16]==8'b00000001 && sector_reg[1] ==1'b1)
1198
        || (check_address[23:16]==8'b00000000 && sector_reg[0] ==1'b1))
1199
                protected = 1'b1;
1200
        else
1201
                protected = 1'b0;
1202
    end
1203
    else if (DEVICE == "AT25DF041A") // un-uniform sectors of AT25DF041A
1204
    begin
1205
        if((check_address[23:14]==10'b00000111_11 && sector_reg[10]==1'b1)
1206
        || (check_address[23:13]==11'b00000111_101 && sector_reg[9]==1'b1)
1207
        || (check_address[23:13]==11'b00000111_100 && sector_reg[8]==1'b1)
1208
        || (check_address[23:15]==9'b00000111_0 && sector_reg[7]   ==1'b1)
1209
        || (check_address[23:16]==8'b00000110 && sector_reg[6]==1'b1)
1210
        || (check_address[23:16]==8'b00000101 && sector_reg[5]==1'b1)
1211
        || (check_address[23:16]==8'b00000100 && sector_reg[4]==1'b1)
1212
        || (check_address[23:16]==8'b00000011 && sector_reg[3]==1'b1)
1213
        || (check_address[23:16]==8'b00000010 && sector_reg[2]==1'b1)
1214
        || (check_address[23:16]==8'b00000001 && sector_reg[1]==1'b1)
1215
        || (check_address[23:16]==8'b00000000 && sector_reg[0]==1'b1))
1216
                protected = 1'b1;
1217
        else
1218
                protected = 1'b0;
1219
    end
1220
        else
1221
        $display("Check Sector Protection failed");
1222
end
1223
endtask
1224
 
1225
// Sending Sector Protection status
1226
task send_protection_status;
1227
integer local_i;
1228
reg [7:0] send_status;   // status value, 'ff' if protected, '00' if unprotected
1229
begin
1230
        if(protected==1'b1)
1231
                send_status = 8'hff;
1232
        else
1233
                send_status = 8'h00;
1234
        local_i = 7;
1235
 
1236
        while (CSB == 1'b0) // continue transmitting, while, CSB is Low
1237
        begin
1238
                @(negedge SCK);
1239
                SO_reg = 1'bx;
1240
                if(HOLDB==1'b0)
1241
                begin
1242
                        #tHLQZ SO_on = 1'b0;
1243
                        wait (HOLDB);
1244
                        #tHHQX;
1245
                end
1246
                #tV;
1247
                SO_reg = send_status[local_i];
1248
                SO_on = 1'b1;
1249
                if (local_i == 0)
1250
                        local_i = 7;
1251
                else
1252
                        local_i = local_i - 1; // next bit
1253
        end // sending status over, because CSB has gone high
1254
end
1255
endtask
1256
 
1257
// receive data for byte/page programming
1258
task page_program;
1259
begin
1260
        pp_j = 0;
1261
        while(CSB==1'b0)
1262
        begin
1263
                for (pp_i=8; pp_i>0; pp_i = pp_i-1)
1264
                begin
1265
                        @(posedge SCK);
1266
                        read_data[pp_i-1] = SI;
1267
                        if(HOLDB==1'b0)
1268
                                wait (HOLDB);
1269
                end
1270
                int_buffer[pp_j] = read_data;
1271
                pp_j = pp_j+1;
1272
        $display("One byte of data: %h received for Page Program",read_data);
1273
        end
1274
end
1275
endtask
1276
 
1277
// Byte program for devices. also used for page program
1278
task byte_program;
1279
input [23:0] write_address;
1280
input [7:0] write_data;
1281
begin
1282
        memory [write_address] = write_data;
1283
        $display ("One Byte of data %h written in memory in location %h", write_data, write_address);
1284
end
1285
endtask
1286
 
1287
// Erase a 4kB block
1288
task erase_4kb;
1289
input [23:0] erase_address;
1290
 
1291
reg [11:0] erase4_i;
1292
reg [23:0] block_addr4;
1293
 
1294
begin
1295
        block_addr4 = {erase_address[23:12],12'b0000_0000_0000};
1296
        $display ("4kB Block with start address %h is going to be erased", block_addr4);
1297
 
1298
        for(erase4_i=12'b0; erase4_i < 12'b1111_1111_1111; erase4_i=erase4_i+1)
1299
        begin
1300
                memory [block_addr4 + erase4_i] = 8'hff;
1301
        end
1302
end
1303
endtask
1304
 
1305
// Erase a 32kB block
1306
task erase_32kb;
1307
input [23:0] erase_address;
1308
 
1309
reg [14:0] erase32_i;
1310
reg [23:0] block_addr32;
1311
 
1312
begin
1313
        block_addr32 = {erase_address[23:15],15'b0000_0000_0000_000};
1314
        $display ("32kB Block with start address %h is going to be erased", block_addr32);
1315
 
1316
        for(erase32_i=15'b0; erase32_i < 15'b1111_1111_1111_111; erase32_i=erase32_i+1)
1317
        begin
1318
                memory [block_addr32 + erase32_i] = 8'hff;
1319
        end
1320
end
1321
endtask
1322
 
1323
// Erase a 64kB block
1324
task erase_64kb;
1325
input [23:0] erase_address;
1326
 
1327
reg [15:0] erase64_i;
1328
reg [23:0] block_addr64;
1329
 
1330
begin
1331
        block_addr64 = {erase_address[23:16],16'b0000_0000_0000_0000};
1332
        $display ("64kB Block with start address %h is going to be erased", block_addr64);
1333
 
1334
        for(erase64_i=0; erase64_i < 16'b1111_1111_1111_1111; erase64_i=erase64_i+1)
1335
        begin
1336
                memory [block_addr64 + erase64_i] = 8'hff;
1337
        end
1338
end
1339
endtask
1340
 
1341
// Chip Erase
1342
task erase_chip;
1343
 
1344
reg [23:0] erase_i;
1345
 
1346
begin
1347
        $display ("Chip Erase is going to be started");
1348
        for(erase_i=0; erase_i < (MEMSIZE-1); erase_i=erase_i+1)
1349
        begin
1350
                memory [erase_i] = 8'hff;
1351
        end
1352
end
1353
endtask
1354
 
1355
// ******************* Execution of Opcodes ********************* //
1356
 
1357
// ************* Deep Power-down ***************** //
1358
always @(EDPD)
1359
begin : EDPD_
1360
        if (RDYnBSY == 1'b1) // device is already busy
1361
        begin
1362
                $display ("Device is busy. Deep Power-down command cannot be issued");
1363
                disable EDPD_ ;
1364
        end
1365
        // if it comes here, means, the above if was false.
1366
 
1367
   //if (freq_error==1'b1)
1368
        //$display("WARNING: Frequency should be less than %d Mhz for SPI interface. Deep Power-down is not allowed.",fSCK);
1369
 
1370
        @ (posedge CSB);
1371
        RDYnBSY = 1'b1;
1372
        #tEDPD deep_power_down = 1'b1;
1373
        RDYnBSY = 1'b0;
1374
        $display ("Device %s enters into Deep Power-down mode. Send 'Resume from Deep Power-down' to resume", DEVICE);
1375
end
1376
 
1377
// ************* Resume from Deep Power-down ***************** //
1378
always @(RDPD)
1379
begin : RDPD_
1380
        if (RDYnBSY == 1'b1) // device is already busy
1381
        begin
1382
                $display ("Device is busy. Deep Power-down command cannot be issued");
1383
                disable EDPD_ ;
1384
        end
1385
        // if it comes here, means, the above if was false.
1386
 
1387
   //if (freq_error==1'b1)
1388
        //$display("WARNING: Frequency should be less than %d Mhz for SPI interface. Resume from Deep Power-down is not allowed.",fSCK);
1389
 
1390
        @ (posedge CSB);
1391
        RDYnBSY = 1'b1;
1392
        #tRDPD deep_power_down = 1'b0;
1393
        RDYnBSY = 1'b0;
1394
        $display ("Device %s Resumes from Deep Power-down mode", DEVICE);
1395
end
1396
 
1397
// ************* Manufacturing ID Read ******************** //
1398
always @(MIR)
1399
begin: MIR_
1400
        if (RDYnBSY == 1'b1) // device is already busy
1401
        begin
1402
                $display ("Device is busy. Manufacturing ID Read cannot be issued");
1403
                disable EDPD_ ;
1404
        end
1405
        // if it comes here, means, the above if was false.
1406
 
1407
   //if (freq_error==1'b1)
1408
        //$display("WARNING: Frequency should be less than %d Mhz for SPI interface. Manufacturing ID Read is not allowed.",fSCK);
1409
 
1410
        j = 32;
1411
        while (CSB == 1'b0)
1412
        begin
1413
                @(negedge SCK);
1414
                SO_reg = 1'bx;
1415
                if(HOLDB==1'b0)
1416
                begin
1417
                        #tHLQZ SO_on = 1'b0;
1418
                        wait (HOLDB);
1419
                        #tHHQX;
1420
                end
1421
                #tV;
1422
                if (j > 0)
1423
                begin
1424
                        SO_reg = MAN_ID[j-1];
1425
                        j = j-1;
1426
                        SO_on = 1'b1;
1427
                        if(j == 0)
1428
                        begin
1429
                                $display ("Manufacture ID and Device ID of Device %s sent", DEVICE);
1430
                                j = 32;
1431
                        end
1432
                end
1433
        end // output next bit on next falling edge of SCK
1434
        $display ("Manufacture ID and Device ID of Device %s sent", DEVICE);
1435
end
1436
 
1437
// ************ Read Status Register ******************** //
1438
always @(RSR)
1439
begin: RSR_
1440
   //if (freq_error==1'b1)
1441
        //$display("WARNING: Frequency should be less than %d Mhz for SPI interface. Status Register Read is not allowed.",fSCK);
1442
 
1443
        status_read = 1'b1; // reading status_reg
1444
        j = 8;
1445
        while (CSB == 1'b0)
1446
        begin
1447
                @(negedge SCK);
1448
                SO_reg = 1'bx;
1449
                if(HOLDB==1'b0)
1450
                begin
1451
                        #tHLQZ SO_on = 1'b0;
1452
                        wait (HOLDB);
1453
                        #tHHQX;
1454
                end
1455
                #tV;
1456
                if (j > 0)
1457
                begin
1458
                        SO_on = 1'b1;
1459
                        SO_reg = status_reg[j-1];
1460
                        j = j-1;
1461
                        if (j == 0)
1462
                        begin
1463
                                j = 8;
1464
                                $display ("Status register content of Device %s transmitted", DEVICE);
1465
                        end
1466
                end
1467
        end // output next bit on next falling edge of SCK
1468
        status_read = 1'b0; // status_reg read is over
1469
end
1470
 
1471
// ************ Write Status Register ******************** //
1472
always @(WSR)
1473
begin : WSR_
1474
        if (RDYnBSY == 1'b1) // device is already busy
1475
        begin
1476
                $display ("Device %s is busy. Write Status Register is not allowed", DEVICE);
1477
                disable WSR_;
1478
        end
1479
        // if it comes here, means, the above if was false.
1480
 
1481
   if (freq_error==1'b1)
1482
        $display("WARNING: Frequency should be less than %d Mhz for SPI interface. Write Status Register is not allowed.",fSCK);
1483
 
1484
        get_data;
1485
        SPRL_val = read_data [7];
1486
        stat_reg_temp = read_data [5:2];
1487
 
1488
        @ (posedge CSB);
1489
        if(WEL==1'b1)
1490
        begin
1491
                if(WPB==1'b0 && SPRL==1'b0 && SPRL_val==1'b1)
1492
                        $display("SPRL Hardware locked");
1493
                else if(WPB==1'b1 && SPRL==1'b0 && SPRL_val==1'b1)
1494
                        $display("SPRL Software locked");
1495
                else if(WPB==1'b0 && SPRL==1'b1 && SPRL_val==1'b1)
1496
                        $display("SPRL Hardware locked. Lock cannot be done");
1497
                else if(WPB==1'b1 && SPRL==1'b1 && SPRL_val==1'b1)
1498
                        $display("SPRL Software locked. Lock cannot be done");
1499
                else if(WPB==1'b0 && SPRL==1'b1 && SPRL_val==1'b0)
1500
                        $display("SPRL Hardware locked. Unlock cannot be done");
1501
                else if(WPB==1'b1 && SPRL==1'b1 && SPRL_val==1'b0)
1502
                        $display("Sector Protection Register UnLocked");
1503
                else
1504
                        $display("SPRL in unlocked state");
1505
 
1506
                if(stat_reg_temp==4'b1111 && SPRL==1'b0)
1507
                        global_protect = 1'b1;
1508
                else if(stat_reg_temp==4'b0000 && SPRL==1'b0)
1509
                        global_unprotect = 1'b1;
1510
                else if(SPRL==1'b1 && (stat_reg_temp==4'b0000 || stat_reg_temp==4'b1111))
1511
                begin
1512
                        $display("SPRL locked. Global Protect/Unprotect cannot be done");
1513
                        global_protect = 1'b0;
1514
                        global_unprotect = 1'b0;
1515
                end
1516
 
1517
                if(SPRL==1'b0 && global_protect==1'b1)
1518
                        $display("Global Protection issued for Sector protection register");
1519
                else if(SPRL==1'b0 && global_unprotect==1'b1)
1520
                        $display("Global Unprotect issued for Sector protection register");
1521
                else if(SPRL==1'b1 && (global_protect==1'b1 || global_unprotect==1'b1))
1522
                        $display("SPRL locked. Global Protect/Unprotect cannot be done");
1523
 
1524
                if(SPRL==1'b0 && SPRL_val==1'b1)
1525
                begin
1526
                        RDYnBSY = 1'b1;
1527
                        lock = 1'b1;
1528
                        #tWRSR;
1529
                end
1530
                else if(SPRL==1'b1 && SPRL_val==1'b0)
1531
                begin
1532
                        RDYnBSY = 1'b1;
1533
                        unlock = 1'b1;
1534
                        #tWRSR;
1535
                end
1536
                else if(global_protect==1'b1 || global_unprotect==1'b1)
1537
                begin
1538
                        RDYnBSY = 1'b1;
1539
                        #tWRSR;
1540
                end
1541
        end
1542
        else
1543
                $display ("WEL bit not set. Write Status Register is not allowed");
1544
 
1545
        lock = 1'b0;
1546
        unlock = 1'b0;
1547
        RDYnBSY = 1'b0;
1548
        global_protect = 1'b0;
1549
        global_unprotect = 1'b0;
1550
        WEL = 1'b0;
1551
        $display ("Write Status Register operation completed");
1552
end
1553
 
1554
// ************ Write Enable ******************** //
1555
always @(WE)
1556
begin : WE_
1557
   if (freq_error==1'b1)
1558
        $display("WARNING: Frequency should be less than %d MHz for SPI interface. Write Enable is not allowed.",fSCK);
1559
 
1560
        @ (posedge CSB);
1561
        WEL = 1'b1;
1562
        $display ("Write Enable Latch Set");
1563
end
1564
 
1565
// ************ Write Disable ******************** //
1566
always @(WD)
1567
begin : WD_
1568
   if (freq_error==1'b1)
1569
        $display("WARNING: Frequency should be less than %d MHz for SPI interface. Write Disable is not allowed.",fSCK);
1570
 
1571
        @ (posedge CSB);
1572
        WEL = 1'b0;
1573
        seq_byte_start = 1'b0;
1574
        SPM = 1'b0;
1575
        $display ("Write Enable Latch Reset");
1576
end
1577
 
1578
// ******************** Read Array ********************** //
1579
always @(RA)
1580
begin : RA_
1581
        if (RDYnBSY == 1'b1) // device is already busy
1582
        begin
1583
                $display ("Device %s is busy. Read Array is not allowed", DEVICE);
1584
                disable RA_;
1585
        end
1586
        // if it comes here, means, the above if was false.
1587
 
1588
   if (freq_error==1'b1)
1589
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. Read Array is not allowed",fSCK);
1590
 
1591
        get_data;
1592
        temp_addr [23:16] = read_data [7:0];
1593
        get_data;
1594
        temp_addr [15:8] = read_data [7:0];
1595
        get_data;
1596
        temp_addr [7:0] = read_data [7:0];
1597
        current_address = temp_addr;
1598
 
1599
        if(rd_dummy==1'b1 && CSB==1'b0) // for SCK freq, receive 8 dummy bits
1600
        begin
1601
                for (dummy = 7; dummy >= 0; dummy = dummy - 1) // these are dont-care, so discarded
1602
                begin
1603
                        @(posedge SCK);
1604
                        read_dummy[dummy] = SI;
1605
                        if(HOLDB==1'b0)
1606
                                wait (HOLDB);
1607
                end
1608
                read_dummy = 8'b0;
1609
        end
1610
 
1611
        read_out_array(current_address); // read continuously from memory untill CSB deasserted
1612
        current_address = 24'b0;
1613
end
1614
 
1615
// ****************** Protect Sector ****************** //
1616
always @(PS)
1617
begin : PS_
1618
        if (RDYnBSY == 1'b1) // device is already busy
1619
        begin
1620
                $display ("Device %s is busy. Protect Sector is not allowed", DEVICE);
1621
                disable PS_ ;
1622
        end
1623
        // if it comes here, means, the above if was false.
1624
 
1625
   if (freq_error==1'b1)
1626
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. Protect Sector is not allowed",fSCK);
1627
 
1628
        get_data;
1629
        temp_addr [23:16] = read_data [7:0];
1630
        get_data;
1631
        temp_addr [15:8] = read_data [7:0];
1632
        get_data;
1633
        temp_addr [7:0] = read_data [7:0];
1634
        current_address = temp_addr;
1635
 
1636
        @ (posedge CSB);
1637
        if(WEL==1'b1 && SPRL==1'b0)
1638
        begin
1639
                RDYnBSY = 1'b1;
1640
                protect = 1'b1;
1641
                protect_sector(current_address);
1642
                #tSECP;
1643
                $display ("Sector for Address %h is Protected", current_address);
1644
        end
1645
        else
1646
                $display ("WEL bit not set or Sector Protection Register Locked. Protect Sector is not allowed");
1647
        WEL = 1'b0;
1648
        RDYnBSY = 1'b0;
1649
        protect = 1'b0;
1650
        current_address = 24'b0;
1651
end
1652
 
1653
// ****************** Un-Protect Sector ****************** //
1654
always @(UPS)
1655
begin : UPS_
1656
        if (RDYnBSY == 1'b1) // device is already busy
1657
        begin
1658
                $display ("Device %s is busy. Un-Protect Sector is not allowed", DEVICE);
1659
                disable UPS_ ;
1660
        end
1661
        // if it comes here, means, the above if was false.
1662
 
1663
   if (freq_error==1'b1)
1664
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. Un-Protect Sector is not allowed",fSCK);
1665
 
1666
        get_data;
1667
        temp_addr [23:16] = read_data [7:0];
1668
        get_data;
1669
        temp_addr [15:8] = read_data [7:0];
1670
        get_data;
1671
        temp_addr [7:0] = read_data [7:0];
1672
        current_address = temp_addr;
1673
 
1674
        @ (posedge CSB);
1675
        if(WEL==1'b1 && SPRL==1'b0)
1676
        begin
1677
                RDYnBSY = 1'b1;
1678
                unprotect = 1'b1;
1679
                unprotect_sector(current_address);
1680
                #tSECUP;
1681
                $display ("Sector for Address %h is UnProtected", current_address);
1682
        end
1683
        else
1684
                $display ("WEL bit not set or Sector Protection Register Locked. Un-Protect Sector is not allowed");
1685
 
1686
        unprotect = 1'b0;
1687
        WEL = 1'b0;
1688
        RDYnBSY = 1'b0;
1689
        current_address = 24'b0;
1690
end
1691
 
1692
// ****************** Read Sector Protection Register ****************** //
1693
always @(RSPR)
1694
begin : RSPR_
1695
        if (RDYnBSY == 1'b1) // device is already busy
1696
        begin
1697
                $display ("Device %s is busy. Read Sector Protection Register is not allowed", DEVICE);
1698
                disable RSPR_ ;
1699
        end
1700
        // if it comes here, means, the above if was false.
1701
 
1702
   if (freq_error==1'b1)
1703
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. Read Sector Protection Register is not allowed",fSCK);
1704
 
1705
        get_data;
1706
        temp_addr [23:16] = read_data [7:0];
1707
        get_data;
1708
        temp_addr [15:8] = read_data [7:0];
1709
        get_data;
1710
        temp_addr [7:0] = read_data [7:0];
1711
        current_address = temp_addr;
1712
 
1713
        check_protection(current_address);
1714
        if(protected==1'b1)
1715
                $display ("Sector for Address %h is Protected", current_address);
1716
        else
1717
                $display ("Sector for Address %h is UnProtected", current_address);
1718
 
1719
        send_protection_status; // sending the Sector Protection Register content in SO
1720
        current_address = 24'b0;
1721
        $display ("Read Sector Protection Register completed");
1722
end
1723
 
1724
// ********************* Byte Program ********************* //
1725
always @(BP)
1726
begin : BP_
1727
        if (RDYnBSY == 1'b1) // device is already busy
1728
        begin
1729
                $display ("Device %s is busy. Byte Program is not allowed", DEVICE);
1730
                disable BP_ ;
1731
        end
1732
        // if it comes here, means, the above if was false.
1733
 
1734
   if (freq_error==1'b1)
1735
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. Byte Program is not allowed",fSCK);
1736
 
1737
        // to receive 3 bytes of address
1738
        get_data;
1739
        temp_addr [23:16] = read_data [7:0];
1740
        get_data;
1741
        temp_addr [15:8] = read_data [7:0];
1742
        get_data;
1743
        temp_addr [7:0] = read_data [7:0];
1744
        current_address = temp_addr;
1745
 
1746
/*
1747
        // to receive 1 bytes of data
1748
        get_data;
1749
        data_in [7:0] = read_data [7:0];
1750
*/
1751
        page_program;   // page program - receives data
1752
 
1753
        if(pp_i < 8)    // page program should not proceed if CSB deasserted at intermediate points
1754
        begin
1755
                $display ("Chip Select deasserted in non-even point. Byte/Page Program is not allowed");
1756
                WEL = 1'b0;
1757
                EPE = 1'b1;
1758
                disable BP_ ;
1759
        end
1760
 
1761
        if(WEL==1'b0)
1762
        begin
1763
                $display ("WEL bit not set. Byte Program is not allowed");
1764
                disable BP_ ;
1765
        end
1766
 
1767
        check_protection(current_address);
1768
 
1769
        if(protected==1'b1)
1770
        begin
1771
                $display("Sector for Address %h is Protected. Byte Program cannot be performed", current_address);
1772
                WEL = 1'b0;
1773
                disable BP_ ;
1774
        end
1775
        else
1776
        begin
1777
                $display ("Sector for Address %h is UnProtected, Byte Program can be performed", current_address);
1778
//              @ (posedge CSB);
1779
                RDYnBSY = 1'b1;
1780
                byte_prog = 1'b1;
1781
                pp_address = current_address[7:0];
1782
 
1783
                for(pp = 0; pp < pp_j; pp = pp+1)
1784
                begin
1785
                        data_in = int_buffer[pp];
1786
                        byte_program({current_address[23:8],pp_address}, data_in);
1787
                        pp_address = pp_address + 1'b1;
1788
                end
1789
                $display("Byte write completed");
1790
 
1791
                #tPP;
1792
                pp               = 0;
1793
                pp_j             = 0;
1794
                pp_i             = 0;
1795
                WEL              = 1'b0;
1796
                RDYnBSY          = 1'b0;
1797
                byte_prog        = 1'b0;
1798
                current_address  = 24'b0;
1799
                pp_address       = 8'b0;
1800
                data_in          = 8'b0;
1801
        end
1802
end
1803
 
1804
// ********************* Sequential Byte Program ********************* //
1805
always @(SBP)
1806
begin : SBP_
1807
        if (RDYnBSY == 1'b1) // device is already busy
1808
        begin
1809
                $display ("Device %s is busy. Sequential Byte Program is not allowed", DEVICE);
1810
                disable SBP_ ;
1811
        end
1812
        // if it comes here, means, the above if was false.
1813
 
1814
   if (freq_error==1'b1)
1815
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. Sequential Byte Program is not allowed",fSCK);
1816
 
1817
        if(seq_byte_start==1'b0)
1818
        begin
1819
        // to receive 3 bytes of address
1820
                get_data;
1821
                temp_addr [23:16] = read_data [7:0];
1822
                get_data;
1823
                temp_addr [15:8] = read_data [7:0];
1824
                get_data;
1825
                temp_addr [7:0] = read_data [7:0];
1826
                current_address = temp_addr;
1827
        end
1828
 
1829
        SPM = 1'b1;     // Entered Sequential Byte Programing mode
1830
 
1831
        if(seq_byte_start==1'b1)        // to increment address when entering sequential mode
1832
        begin
1833
                if(current_address < (MEMSIZE-1))
1834
                        current_address = current_address + 1'b1;
1835
                else if(current_address == (MEMSIZE-1))
1836
                begin
1837
                        $display ("Sequential Byte Program for device: %s reaches end of memory (%h). No Wrapping allowed. Sequential Byte Program is not allowed", DEVICE, MEMSIZE-1);
1838
                        WEL = 1'b0;
1839
                        SPM = 1'b0;
1840
                        seq_byte_start = 1'b0;
1841
                        disable SBP_ ;
1842
                end
1843
        end
1844
 
1845
        // to receive 1 bytes of data
1846
        get_data;
1847
        data_in [7:0] = read_data [7:0];
1848
 
1849
        if(WEL==1'b0)
1850
        begin
1851
                $display ("WEL bit not set. Sequential Byte Program is not allowed");
1852
                seq_byte_start = 1'b0;
1853
                SPM = 1'b0;
1854
                disable SBP_ ;
1855
        end
1856
 
1857
        check_protection(current_address);
1858
 
1859
        if(protected==1'b1)
1860
        begin
1861
                $display("Sector for Address %h is Protected. Sequential Byte Program cannot be performed", current_address);
1862
                seq_byte_start = 1'b0;
1863
                WEL = 1'b0;
1864
                SPM = 1'b0;
1865
                disable SBP_ ;
1866
        end
1867
        else
1868
        begin
1869
                $display ("Sector for Address %h is UnProtected, Sequential Byte Program can be performed", current_address);
1870
                @ (posedge CSB);
1871
                RDYnBSY = 1'b1;
1872
                seq_byte_prog = 1'b1;
1873
 
1874
                byte_program(current_address, data_in);
1875
                $display("Sequential Byte write completed");
1876
 
1877
                #tBP;
1878
                RDYnBSY = 1'b0;
1879
                seq_byte_prog = 1'b0;
1880
                data_in = 8'b0;
1881
                seq_byte_start = 1'b1;
1882
        end
1883
end
1884
 
1885
// ********************* 4kB Block Erase ********************* //
1886
always @(BE4)
1887
begin : BE4_
1888
        if (RDYnBSY == 1'b1) // device is already busy
1889
        begin
1890
                $display ("Device %s is busy. 4KB Block Erase is not allowed", DEVICE);
1891
                disable BE4_ ;
1892
        end
1893
        // if it comes here, means, the above if was false.
1894
 
1895
   if (freq_error==1'b1)
1896
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. 4KB Block Erase is not allowed",fSCK);
1897
 
1898
        get_data;
1899
        temp_addr [23:16] = read_data [7:0];
1900
        get_data;
1901
        temp_addr [15:8] = read_data [7:0];
1902
        get_data;
1903
        temp_addr [7:0] = read_data [7:0];
1904
        current_address = temp_addr;
1905
 
1906
        if(WEL==1'b0)
1907
        begin
1908
                $display ("WEL bit not set. 4KB Block Erase is not allowed");
1909
                disable BE4_ ;
1910
        end
1911
 
1912
        check_protection(current_address);
1913
 
1914
        if(protected==1'b1)
1915
        begin
1916
                $display("Sector for Address %h is Protected. 4KB Block Erase cannot be performed", current_address);
1917
                WEL = 1'b0;
1918
                disable BE4_ ;
1919
        end
1920
        else
1921
        begin
1922
                $display ("Sector for Address %h is UnProtected, 4KB Block Erase can be performed", current_address);
1923
                @ (posedge CSB);
1924
                RDYnBSY = 1'b1;
1925
                erasing_block4 = 1'b1;
1926
 
1927
                erase_4kb(current_address);
1928
                #tBLKE4;
1929
 
1930
                $display ("4kB Block with start address %h erased", {current_address[23:12],12'b0});
1931
                WEL = 1'b0;
1932
                RDYnBSY = 1'b0;
1933
                current_address = 24'b0;
1934
                erasing_block4 = 1'b0;
1935
        end
1936
end
1937
 
1938
// ********************* 32kB Block Erase ********************* //
1939
always @(BE32)
1940
begin : BE32_
1941
        if (RDYnBSY == 1'b1) // device is already busy
1942
        begin
1943
                $display ("Device %s is busy. 32KB Block Erase is not allowed", DEVICE);
1944
                disable BE32_ ;
1945
        end
1946
        // if it comes here, means, the above if was false.
1947
 
1948
   if (freq_error==1'b1)
1949
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. 32KB Block Erase is not allowed",fSCK);
1950
 
1951
        get_data;
1952
        temp_addr [23:16] = read_data [7:0];
1953
        get_data;
1954
        temp_addr [15:8] = read_data [7:0];
1955
        get_data;
1956
        temp_addr [7:0] = read_data [7:0];
1957
        current_address = temp_addr;
1958
 
1959
        if(WEL==1'b0)
1960
        begin
1961
                $display ("WEL bit not set. 32KB Block Erase is not allowed");
1962
                disable BE32_ ;
1963
        end
1964
 
1965
        if(DEVICE == "AT25DF041A" && current_address[23:15]==9'b0000_0111_1)
1966
        begin
1967
                check_protection({current_address[23:16],2'b11,14'b0});
1968
                if(protected==1'b1)
1969
                begin
1970
                        $display("Sector for Address %h is Protected. 32KB Block Erase cannot be performed", {current_address[23:16],2'b11,14'b0});
1971
                        EPE = 1'b1;
1972
                        WEL = 1'b0;
1973
                        disable BE32_ ;
1974
                end
1975
                check_protection({current_address[23:16],3'b100,13'b0});
1976
                if(protected==1'b1)
1977
                begin
1978
                        $display("Sector for Address %h is Protected. 32KB Block Erase cannot be performed", {current_address[23:16],3'b100,13'b0});
1979
                        EPE = 1'b1;
1980
                        WEL = 1'b0;
1981
                        disable BE32_ ;
1982
                end
1983
                check_protection({current_address[23:16],3'b101,13'b0});
1984
                if(protected==1'b1)
1985
                begin
1986
                        $display("Sector for Address %h is Protected. 32KB Block Erase cannot be performed", {current_address[23:16],3'b101,13'b0});
1987
                        EPE = 1'b1;
1988
                        WEL = 1'b0;
1989
                        disable BE32_ ;
1990
                end
1991
        end
1992
        else if(DEVICE == "AT26DF081A" && current_address[23:15]==9'b0000_1111_0)
1993
        begin
1994
                check_protection({current_address[23:16],2'b00,15'b0});
1995
                if(protected==1'b1)
1996
                begin
1997
                        $display("Sector for Address %h is Protected. 32KB Block Erase cannot be performed", {current_address[23:16],2'b00,15'b0});
1998
                        EPE = 1'b1;
1999
                        WEL = 1'b0;
2000
                        disable BE32_ ;
2001
                end
2002
                check_protection({current_address[23:16],3'b010,13'b0});
2003
                if(protected==1'b1)
2004
                begin
2005
                        $display("Sector for Address %h is Protected. 32KB Block Erase cannot be performed", {current_address[23:16],3'b010,13'b0});
2006
                        EPE = 1'b1;
2007
                        WEL = 1'b0;
2008
                        disable BE32_ ;
2009
                end
2010
                check_protection({current_address[23:16],3'b011,13'b0});
2011
                if(protected==1'b1)
2012
                begin
2013
                        $display("Sector for Address %h is Protected. 32KB Block Erase cannot be performed", {current_address[23:16],3'b011,13'b0});
2014
                        EPE = 1'b1;
2015
                        WEL = 1'b0;
2016
                        disable BE32_ ;
2017
                end
2018
        end
2019
        else
2020
                check_protection(current_address);
2021
 
2022
        if(protected==1'b1)
2023
        begin
2024
                $display("Sector for Address %h is Protected. 32KB Block Erase cannot be performed", current_address);
2025
                WEL = 1'b0;
2026
                disable BE32_ ;
2027
        end
2028
        else
2029
        begin
2030
                $display ("Sector for Address %h is UnProtected, 32KB Block Erase can be performed", current_address);
2031
                @ (posedge CSB);
2032
                RDYnBSY = 1'b1;
2033
                erasing_block32 = 1'b1;
2034
 
2035
                erase_32kb(current_address);
2036
                #tBLKE32;
2037
 
2038
                $display ("32KB Block with start address %h erased", {current_address[23:15],15'b0});
2039
                WEL = 1'b0;
2040
                RDYnBSY = 1'b0;
2041
                current_address = 24'b0;
2042
                erasing_block32 = 1'b0;
2043
        end
2044
end
2045
 
2046
// ********************* 64kB Block Erase ********************* //
2047
always @(BE64)
2048
begin : BE64_
2049
        if (RDYnBSY == 1'b1) // device is already busy
2050
        begin
2051
                $display ("Device %s is busy. 64KB Block Erase is not allowed", DEVICE);
2052
                disable BE64_ ;
2053
        end
2054
        // if it comes here, means, the above if was false.
2055
 
2056
   if (freq_error==1'b1)
2057
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. 64KB Block Erase is not allowed",fSCK);
2058
 
2059
        get_data;
2060
        temp_addr [23:16] = read_data [7:0];
2061
        get_data;
2062
        temp_addr [15:8] = read_data [7:0];
2063
        get_data;
2064
        temp_addr [7:0] = read_data [7:0];
2065
        current_address = temp_addr;
2066
 
2067
        if(WEL==1'b0)
2068
        begin
2069
                $display ("WEL bit not set. 64KB Block Erase is not allowed");
2070
                disable BE64_ ;
2071
        end
2072
 
2073
        if(DEVICE == "AT25DF041A" && current_address[23:16]==8'b0000_0111)
2074
        begin
2075
                check_protection({current_address[23:16],1'b0,15'b0});
2076
                if(protected==1'b1)
2077
                begin
2078
                        $display("Sector for Address %h is Protected. 64KB Block Erase cannot be performed", {current_address[23:16],1'b0,15'b0});
2079
                        EPE = 1'b1;
2080
                        WEL = 1'b0;
2081
                        disable BE64_ ;
2082
                end
2083
                check_protection({current_address[23:16],2'b11,14'b0});
2084
                if(protected==1'b1)
2085
                begin
2086
                        $display("Sector for Address %h is Protected. 64KB Block Erase cannot be performed", {current_address[23:16],2'b11,14'b0});
2087
                        EPE = 1'b1;
2088
                        WEL = 1'b0;
2089
                        disable BE64_ ;
2090
                end
2091
                check_protection({current_address[23:16],3'b100,13'b0});
2092
                if(protected==1'b1)
2093
                begin
2094
                        $display("Sector for Address %h is Protected. 64KB Block Erase cannot be performed", {current_address[23:16],3'b100,13'b0});
2095
                        EPE = 1'b1;
2096
                        WEL = 1'b0;
2097
                        disable BE64_ ;
2098
                end
2099
                check_protection({current_address[23:16],3'b101,13'b0});
2100
                if(protected==1'b1)
2101
                begin
2102
                        $display("Sector for Address %h is Protected. 64KB Block Erase cannot be performed", {current_address[23:16],3'b101,13'b0});
2103
                        EPE = 1'b1;
2104
                        WEL = 1'b0;
2105
                        disable BE64_ ;
2106
                end
2107
        end
2108
        else if(DEVICE == "AT26DF081A" && current_address[23:16]==8'b0000_1111)
2109
        begin
2110
                check_protection({current_address[23:16],2'b00,15'b0});
2111
                if(protected==1'b1)
2112
                begin
2113
                        $display("Sector for Address %h is Protected. 64KB Block Erase cannot be performed", {current_address[23:16],2'b00,15'b0});
2114
                        EPE = 1'b1;
2115
                        WEL = 1'b0;
2116
                        disable BE64_ ;
2117
                end
2118
                check_protection({current_address[23:16],1'b1,14'b0});
2119
                if(protected==1'b1)
2120
                begin
2121
                        $display("Sector for Address %h is Protected. 64KB Block Erase cannot be performed", {current_address[23:16],1'b1,14'b0});
2122
                        EPE = 1'b1;
2123
                        WEL = 1'b0;
2124
                        disable BE64_ ;
2125
                end
2126
                check_protection({current_address[23:16],3'b010,13'b0});
2127
                if(protected==1'b1)
2128
                begin
2129
                        $display("Sector for Address %h is Protected. 64KB Block Erase cannot be performed", {current_address[23:16],3'b010,13'b0});
2130
                        EPE = 1'b1;
2131
                        WEL = 1'b0;
2132
                        disable BE64_ ;
2133
                end
2134
                check_protection({current_address[23:16],3'b011,13'b0});
2135
                if(protected==1'b1)
2136
                begin
2137
                        $display("Sector for Address %h is Protected. 64KB Block Erase cannot be performed", {current_address[23:16],3'b011,13'b0});
2138
                        EPE = 1'b1;
2139
                        WEL = 1'b0;
2140
                        disable BE64_ ;
2141
                end
2142
        end
2143
        else
2144
                check_protection(current_address);
2145
 
2146
        if(protected==1'b1)
2147
        begin
2148
                $display("Sector for Address %h is Protected. 64KB Block Erase cannot be performed", current_address);
2149
                WEL = 1'b0;
2150
                disable BE64_ ;
2151
        end
2152
        else
2153
        begin
2154
                $display ("Sector for Address %h is UnProtected, 64KB Block Erase can be performed", current_address);
2155
                @ (posedge CSB);
2156
                RDYnBSY = 1'b1;
2157
                erasing_block64 = 1'b1;
2158
 
2159
                erase_64kb(current_address);
2160
                #tBLKE64;
2161
 
2162
                $display ("64kB Block with start address %h erased", {current_address[23:16],16'b0});
2163
                WEL = 1'b0;
2164
                RDYnBSY = 1'b0;
2165
                current_address = 24'b0;
2166
                erasing_block64 = 1'b0;
2167
        end
2168
end
2169
 
2170
// ********************* Chip Erase ********************* //
2171
always @(CE)
2172
begin : CE_
2173
        if (RDYnBSY == 1'b1) // device is already busy
2174
        begin
2175
                $display ("Device %s is busy. Chip Erase is not allowed", DEVICE);
2176
                disable CE_ ;
2177
        end
2178
        // if it comes here, means, the above if was false.
2179
 
2180
   if (freq_error==1'b1)
2181
        $display ("WARNING: Frequency should be less than %d MHz for SPI interface. Chip Erase is not allowed",fSCK);
2182
 
2183
        if(WEL==1'b0)
2184
        begin
2185
                $display ("WEL bit not set. Chip Erase is not allowed");
2186
                disable CE_ ;
2187
        end
2188
 
2189
        if(SWP==2'b00)
2190
        begin
2191
                $display("All Sectors in the chip are UnProtected. Chip Erase can be performed");
2192
                @ (posedge CSB);
2193
                RDYnBSY = 1'b1;
2194
                erasing_chip = 1'b1;
2195
 
2196
                erase_chip;
2197
                for(delay =0; delay < tmult; delay = delay+1)
2198
                        #tCHPEn;
2199
 
2200
                WEL = 1'b0;
2201
                RDYnBSY = 1'b0;
2202
                erasing_chip = 1'b0;
2203
        end
2204
        else if(SWP!=2'b00)
2205
        begin
2206
                $display("Some or all Sectors in the chip is Protected. Chip Erase cannot be performed");
2207
                EPE = 1'b1;
2208
                disable CE_ ;
2209
        end
2210
 
2211
        $display ("Chip Erase Completed");
2212
end
2213
 
2214
// ******** Posedge CSB. Stop all reading, recvng. commands/addresses etc. ********* //
2215
 
2216
always @(posedge CSB)
2217
begin
2218
        disable RA_;    // Read Array (low freq and normal freq)
2219
        disable MIR_;   // MIR will stop, if CSB goes high
2220
        disable RSR_;   // Status reading should stop.
2221
 
2222
        disable get_opcode;             // Stop opcode retrieval
2223
        disable get_data;               // Stop address/data retrieval
2224
        disable read_out_array;         // send data in SO
2225
        disable send_protection_status; // Send Protection status
2226
        disable page_program;
2227
 
2228
        temp_data = 8'b0;
2229
        temp_addr = 24'b0;
2230
        rd_dummy = 1'b0;
2231
        status_read = 1'b0;
2232
        protected = 1'b0;
2233
        read_data = 8'b0;
2234
        EPE = 1'b0;
2235
 
2236
        #tDIS SO_on = 1'b0;  // SO is now in high-impedance
2237
        SO_reg = 1'b0;
2238
end
2239
 
2240
// ********************** Frequeny Checking ********************** //
2241
always @ (negedge SCK)
2242
begin
2243
        tperiod <= $time;
2244
        tperiod1 <= tperiod;
2245
end
2246
 
2247
//always @(tperiod or tperiod1)
2248
always @(negedge SCK)
2249
begin
2250
        if ((tperiod - tperiod1) < (tSCKH + tSCKH))
2251
        begin
2252
                //freq_error = 1'b1;
2253
                //$display("Frequency exceeds max limit (14285 ms). Time period detected is %t", (tperiod -tperiod1)); 
2254
        end
2255
        else
2256
                freq_error = 1'b0;
2257
 
2258
end // always
2259
// **************************************************************** //
2260
 
2261
endmodule

powered by: WebSVN 2.1.0

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