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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [bench/] [verilog/] [AT26DFxxx.v] - Blame information for rev 30

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

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

powered by: WebSVN 2.1.0

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