OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

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

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

powered by: WebSVN 2.1.0

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