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

Subversion Repositories turbo8051

[/] [turbo8051/] [trunk/] [verif/] [agents/] [spi/] [atmel/] [AT45DBXXX_v2.0.3.v] - Blame information for rev 76

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 dinesha
/************************************************************************
2
 
3
        Verilog model for Atmel Devices
4
          AT45DBXXX  parameterizable
5
 
6
            Developed for Atmel By:
7
                Jason G Brown
8
                Glenn Donovan
9
                 Jeff Gladu
10
 
11
              January 24, 2002
12
 
13
************************************************************************/
14
 
15
/************************************************************************
16
Development History:
17
 
18
  AT45DBXXX model : Sanjay Churiwala, May-June 1999
19
  Parameterized   : Niranjan Vaish, June 1999
20
 
21
Revision History:
22
 
23
1.0    : Niranjan Vaish   : Parametrized model for AT45DBXXX devices.
24
1.1    : Niranjan Vaish   : Updated RDY_BUSYB driving register.
25
2.0    : Niranjan Vaish   : 2M, 4M and 8M also offer Page Erase and Block Erase.
26
2.0.1  : Niranjan Vaish   : buffer1 and buffer2 were not declared correctly.
27
2.0.2  : Niranjan Vaish   : Additional parametrization has been done.
28
2.0.3  : WPI Project Team : Removed Burst Mode.
29
 
30
*************************************************************************/
31
 
32
 
33
/*************************************************************************
34
 Define the configuration which you want to use.
35
*************************************************************************/
36
//`define device4M 1  // This model will work like AT45DB041
37
`define device32M 1  // This model will work like AT45DB321
38
 
39
 
40
/*************************************************************************/
41
 
42
`ifdef device1M
43
module AT45DB011 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
44
`endif
45
 
46
`ifdef device2M
47
module AT45DB021 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
48
`endif
49
 
50
`ifdef device4M
51
module AT45DB041 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
52
`endif
53
 
54
`ifdef device8M
55
module AT45DB081 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
56
`endif
57
 
58
`ifdef device16M
59
module AT45DB161 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
60
`endif
61
 
62
`ifdef device32M
63
module AT45DB321 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
64
`endif
65
 
66
input CSB, SCK, SI, WPB, RESETB;
67
output SO, RDY_BUSYB;
68
 
69
/*************************************************************************
70
Device configuration parameters :
71
*************************************************************************/
72
 
73
`ifdef device1M
74
parameter DEVICE = "AT45DB011";
75
parameter MEMSIZE = 135168; // no of byte_news = PAGESIZE * PAGES
76
parameter PAGESIZE = 264; // no of byte_news per page
77
parameter PAGES = 512; // no of pages
78
parameter STATUS3 = 1;  // this and next two lines are for
79
                               //bits 3 to 5 of status register
80
parameter STATUS4 = 0;
81
parameter STATUS5 = 0;
82
parameter BUFFERS = 1; // no. of buffers
83
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
84
parameter PADDRESS = 9; // no of bits needed to access a page
85
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
86
`endif
87
 
88
`ifdef device2M
89
parameter DEVICE = "AT45DB021";
90
parameter MEMSIZE = 270336; // no of byte_news = PAGESIZE * PAGES
91
parameter PAGESIZE = 264; // no of byte_news per page
92
parameter PAGES = 1024; // no of pages
93
parameter STATUS3 = 0;  // this and next two lines are for
94
                               //bits 3 to 5 of status register
95
parameter STATUS4 = 1;
96
parameter STATUS5 = 0;
97
parameter BUFFERS = 2; // no. of buffers
98
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
99
parameter PADDRESS = 10; // no of bits needed to access a page
100
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
101
`endif
102
 
103
`ifdef device4M
104
parameter DEVICE = "AT45DB041";
105
parameter MEMSIZE = 540672; // no of byte_news = PAGESIZE * PAGES
106
parameter PAGESIZE = 264; // no of byte_news per page
107
parameter PAGES = 2048; // no of pages
108
parameter STATUS3 = 1;  // this and next two lines are for
109
                               //bits 3 to 5 of status register
110
parameter STATUS4 = 1;
111
parameter STATUS5 = 0;
112
parameter BUFFERS = 2; // no. of buffers
113
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
114
parameter PADDRESS = 11; // no of bits needed to access a page
115
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
116
`endif
117
 
118
`ifdef device8M
119
parameter DEVICE = "AT45DB081";
120
parameter MEMSIZE = 1081344; // no of byte_news = PAGESIZE * PAGES
121
parameter PAGESIZE = 264; // no of byte_news per page
122
parameter PAGES = 4096; // no of pages
123
parameter STATUS3 = 0;  // this and next two lines are for
124
                               //bits 3 to 5 of status register
125
parameter STATUS4 = 0;
126
parameter STATUS5 = 1;
127
parameter BUFFERS = 2; // no. of buffers
128
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
129
parameter PADDRESS = 12; // no of bits needed to access a page
130
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
131
`endif
132
 
133
`ifdef device16M
134
parameter DEVICE = "AT45DB161";
135
parameter MEMSIZE = 2162688; // no of byte_news = PAGESIZE * PAGES
136
parameter PAGESIZE = 528; // no of byte_news per page
137
parameter PAGES = 4096; // no of pages
138
parameter STATUS3 = 1;  // this and next two lines are for
139
                               //bits 3 to 5 of status register
140
parameter STATUS4 = 0;
141
parameter STATUS5 = 1;
142
parameter BUFFERS = 2; // no. of buffers
143
parameter BADDRESS = 10; // no of bits needed to access a byte_new within a page
144
parameter PADDRESS = 12; // no of bits needed to access a page
145
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
146
`endif
147
 
148
 
149
 
150
`ifdef device32M
151
parameter DEVICE = "AT45DB321";
152
//parameter MEMSIZE = 4194304; // no of byte_news = PAGESIZE * PAGES
153
parameter MEMSIZE = 4325376; // no of byte_news = PAGESIZE * PAGES
154
parameter PAGESIZE = 528; // no of byte_news per page
155
parameter PAGES = 8192; // no of pages
156
parameter STATUS3 = 0;  // this and next two lines are for 
157
                               //bits 3 to 5 of status register
158
parameter STATUS4 = 1;
159
parameter STATUS5 = 1;
160
parameter BUFFERS = 2; // no. of buffers
161
parameter BADDRESS = 10; // no of bits needed to access a byte_new within a page
162
parameter PADDRESS = 13; // no of bits needed to access a page
163
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
164
`endif
165
 
166
/********************************************************************
167
Timing Parameters :
168
More timing parameters given as specparam within the specify block
169
********************************************************************/
170
 
171
`ifdef device1M
172
parameter tDIS = 25;
173
parameter tV = 30;
174
parameter tXFR = 200000;
175
parameter tEP = 20000000;
176
parameter tP = 15000000;
177
parameter tPE = 10000000;
178
parameter tBE = 15000000;
179
parameter tCAR = 200;
180
`endif
181
 
182
`ifdef device2M
183
parameter tDIS = 25;
184
parameter tV = 30;
185
parameter tXFR = 250000;
186
parameter tEP = 20000000;
187
parameter tP = 14000000;
188
parameter tPE = 10000000; // Correct it
189
parameter tBE = 15000000; // Correct it
190
parameter tCAR = 200;
191
`endif
192
 
193
`ifdef device4M
194
parameter tDIS = 25;
195
parameter tV = 30;
196
parameter tXFR = 250000;
197
parameter tEP = 20000000;
198
parameter tP = 14000000;
199
parameter tPE = 10000000;
200
parameter tBE = 15000000;
201
parameter tCAR = 200;
202
`endif
203
 
204
`ifdef device8M
205
parameter tDIS = 25;
206
parameter tV = 30;
207
parameter tXFR = 200000;
208
parameter tEP = 20000000;
209
parameter tP = 14000000;
210
parameter tPE = 10000000; // Correct it
211
parameter tBE = 15000000; // Correct it
212
parameter tCAR = 200;
213
`endif
214
 
215
`ifdef device16M
216
parameter tDIS = 25;
217
parameter tV = 30;
218
parameter tXFR = 350000;
219
parameter tEP = 20000000;
220
parameter tP = 15000000;
221
parameter tPE = 10000000;
222
parameter tBE = 15000000;
223
parameter tCAR = 200;
224
`endif
225
 
226
`ifdef device32M
227
`ifdef ATFLASH_SPDUP
228
parameter tDIS = 25;
229
parameter tV = 30;
230
parameter tXFR = 35000;
231
parameter tEP = 20000;
232
parameter tP = 15000;
233
parameter tPE = 10000;
234
parameter tBE = 15000;
235
parameter tCAR = 200;
236
`else
237
parameter tDIS = 25;
238
parameter tV = 30;
239
parameter tXFR = 350000;
240
parameter tEP = 20000000;
241
parameter tP = 15000000;
242
parameter tPE = 10000000;
243
parameter tBE = 15000000;
244
parameter tCAR = 200;
245
`endif
246
`endif
247
 
248
 
249
/**********************************************************************
250
Memory PreLoading Parameters:
251
=============================
252
These parameters are related to Memory-Preloading. Since, we had to declare
253
multiple memories, due to Verilog limitation; for PreLoading also, one may
254
have to preload multiple memories.
255
Any of the memories can be preloaded, in either Hex format, or, in Binary
256
To load a memory (say memory0) in Hex format, define parameter: mem0_h
257
To load a memory (say memory0) in Binary format, define parameter: mem0_b
258
If none of the parameters are specified, the memory will be initialized to
259
    Erase state.
260
If both of the parameters are specified, the hex file will be used.
261
If any of the memory locations are initialized, the status of all the page
262
   will be Not-Erased.
263
**********************************************************************/
264
`ifdef SPI_PRELOAD_FNAME
265
parameter mem0_h = `SPI_PRELOAD_FNAME;
266
`else
267
parameter mem0_h = "";
268
`endif
269
parameter mem1_h = "";
270
parameter mem2_h = "";
271
parameter mem3_h = "";
272
parameter mem4_h = "";
273
parameter mem5_h = "";
274
parameter mem6_h = "";
275
parameter mem7_h = "";
276
 
277
parameter mem0_b = "";
278
parameter mem1_b = "";
279
parameter mem2_b = "";
280
parameter mem3_b = "";
281
parameter mem4_b = "";
282
parameter mem5_b = "";
283
parameter mem6_b = "";
284
parameter mem7_b = "";
285
 
286
/********* Memory And Access Related Declarations *****************/
287
// Verilog seems to be having a restriction due to which, large
288
// memory-registers can not be used. Hence, declaring 8 smaller,
289
// equal size memories.
290
 
291
reg [7:0] memory0 [540671:0] ;
292
reg [7:0] memory1 [1081343:540672] ;
293
reg [7:0] memory2 [1622015:1081344] ;
294
reg [7:0] memory3 [2162687:1622016] ;
295
reg [7:0] memory4 [2703359:2162688] ;
296
reg [7:0] memory5 [3244031:2703360] ;
297
reg [7:0] memory6 [3784703:3244032] ;
298
reg [7:0] memory7 [4325375:3784704] ;
299
 
300
reg [7:0] buffer1 [PAGESIZE-1:0] ; //Buffer 1
301
reg [7:0] buffer2 [PAGESIZE-1:0] ; //Buffer 2
302
 
303
reg [PADDRESS-1:0] page ; // page address
304
reg [BADDRESS-1:0] byte_new ; // byte_new address
305
reg [7:0] status ; // status reg
306
reg [PAGES-1:0] page_status;  // 0 means page-erased, otherwise not erased
307
 
308
 
309
/********* Events to trigger some task based on opcode ***********/
310
     event  MMPR ;  // Main Memory Page Read
311
     event  B1R ;   // Buffer 1 Read
312
     event  B2R ;   // Buffer 2 Read
313
     event  MMPTB1T ;   // Main Memory Page To Buffer 1 Transfer
314
     event  MMPTB2T ;   // Main Memory Page To Buffer 2 Transfer
315
     event  MMPTB1C ;   // Main Memory Page To Buffer 1 Compare
316
     event  MMPTB2C ;   // Main Memory Page To Buffer 2 Compare
317
     event  B1W ;   // Buffer 1 Write
318
     event  B2W ;   // Buffer 2 Write
319
     event  B1TMMPPWBIE ;   // Buffer 1 To Main Memory Page Prog 
320
                                     //With Built-In Erase 
321
     event  B2TMMPPWBIE ;   // Buffer 2 To Main Memory Page Prog 
322
                                     //With Built-In Erase 
323
     event  B1TMMPPWOBIE ;   // Buffer 1 To Main Memory Page Prog 
324
                                     //WithoOut Built-In Erase 
325
     event  B2TMMPPWOBIE ;   // Buffer 2 To Main Memory Page Prog 
326
                                     //WithoOut Built-In Erase 
327
     event  PE ;   // Page Erase
328
     event  BE ;   // Block Erase
329
     event  MMPPB1 ;   // Main Memory Page Prog. Through Buffer 1
330
     event  MMPPB2 ;   // Main Memory Page Prog. Through Buffer 2
331
     event  APRB1 ;   // Auto Page Rewrite Through Buffer 1
332
     event  APRB2 ;   // Auto Page Rewrite Through Buffer 2
333
     event  SR ;   // Status Register Read
334
     event  RWOPR ; // This is basically same as MMPR, except that rollover
335
                    // at the end of a page does not occur;
336
 
337
/********* Registers to track the current operation of the device ********/
338
reg status_read;
339
reg updating_buffer1;
340
reg updating_buffer2;
341
reg updating_memory;
342
reg comparing;
343
reg erasing_page;
344
reg erasing_block;
345
reg skip; // reg to denote whether or no an extra clock needs to be skipped.
346
          // This skipping is needed only for Inactive Clock Low. 
347
 
348
 
349
/******** Other variables/registers/events ******************/
350
reg [7:0] read_data; // temp. register in which data is read-in
351
reg [7:0] temp_reg1; // temp. register to store temporary data
352
reg [7:0] temp_reg2; // temp. register to store temporary data
353
reg [PADDRESS-1:0] temp_page; // temp register to store page-address
354
reg SO_reg , SO_on ;
355
reg RDYBSY_reg;
356
integer j;
357
integer page_boundary_low, page_boundary_high, current_address;
358
integer mem_no; // this will keep track of the actual memory to be used.
359
reg mem_initialized;
360
 
361
 
362
/********* Drive SO ***********************/
363
bufif1 (SO, SO_reg, SO_on); //SO will be driven only if SO_on is High
364
bufif1 (RDY_BUSYB, 1'b0, RDYBSY_reg); //RDYBUSYB will be driven only if RDYBSY_reg is High
365
 
366
 
367
/********* Initialize **********************/
368
initial
369
begin
370
    // start with erased state
371
    // Memory Initialization
372
  mem_initialized = 1'b0;
373
 
374
  for (j=0; j<540672; j=j+1)   // Pre-initiazliation to Erased
375
  begin                        // state is useful if a user wants to
376
    memory0[j] = 8'hff;        // initialize just a few locations.
377
    memory1[j+540672] = 8'hff;
378
    memory2[j+1081344] = 8'hff;
379
    memory3[j+1622016] = 8'hff;
380
    memory4[j+2162688] = 8'hff;
381
    memory5[j+2703360] = 8'hff;
382
    memory6[j+3244032] = 8'hff;
383
    memory7[j+3784704] = 8'hff;
384
  end
385
 
386
   // Now preload, if needed
387
  if (mem0_h != "")
388
  begin
389
     $readmemh (mem0_h, memory0);
390
     mem_initialized = 1'b1;
391
  end
392
  else if (mem0_b != "")
393
  begin
394
     $readmemb (mem0_b, memory0);
395
     mem_initialized = 1'b1;
396
  end
397
 
398
  if (mem1_h != "")
399
  begin
400
     $readmemh (mem1_h, memory1);
401
     mem_initialized = 1'b1;
402
  end
403
  else if (mem1_b != "")
404
  begin
405
     $readmemb (mem1_b, memory1);
406
     mem_initialized = 1'b1;
407
  end
408
 
409
  if (mem2_h != "")
410
  begin
411
     $readmemh (mem2_h, memory2);
412
     mem_initialized = 1'b1;
413
  end
414
  else if (mem2_b != "")
415
  begin
416
     $readmemb (mem2_b, memory2);
417
     mem_initialized = 1'b1;
418
  end
419
 
420
  if (mem3_h != "")
421
  begin
422
     $readmemh (mem3_h, memory3);
423
     mem_initialized = 1'b1;
424
  end
425
  else if (mem3_b != "")
426
  begin
427
     $readmemb (mem3_b, memory3);
428
     mem_initialized = 1'b1;
429
  end
430
 
431
  if (mem4_h != "")
432
  begin
433
     $readmemh (mem4_h, memory4);
434
     mem_initialized = 1'b1;
435
  end
436
  else if (mem4_b != "")
437
  begin
438
     $readmemb (mem4_b, memory4);
439
     mem_initialized = 1'b1;
440
  end
441
 
442
  if (mem5_h != "")
443
  begin
444
     $readmemh (mem5_h, memory5);
445
     mem_initialized = 1'b1;
446
  end
447
  else if (mem5_b != "")
448
  begin
449
     $readmemb (mem5_b, memory5);
450
     mem_initialized = 1'b1;
451
  end
452
 
453
  if (mem6_h != "")
454
  begin
455
     $readmemh (mem6_h, memory6);
456
     mem_initialized = 1'b1;
457
  end
458
  else if (mem6_b != "")
459
  begin
460
     $readmemb (mem6_b, memory6);
461
     mem_initialized = 1'b1;
462
  end
463
 
464
  if (mem7_h != "")
465
  begin
466
     $readmemh (mem7_h, memory7);
467
     mem_initialized = 1'b1;
468
  end
469
  else if (mem7_b != "")
470
  begin
471
     $readmemb (mem7_b, memory7);
472
     mem_initialized = 1'b1;
473
  end
474
 
475
  if (mem_initialized == 1'b1)
476
  for (j=0; j<PAGES; j=j+1)
477
    page_status[j] = 1'b1; // memory was initialized, so, Pages are Not Erased.
478
  else
479
  for (j=0; j<PAGES; j=j+1)
480
    page_status[j] = 1'b0;
481
 
482
  // Now initialize all registers
483
  status[7] = 1'b1; // device is ready to start with
484
  status[6] = 1'bx; // compare bit is unknown
485
  status[5] = STATUS5;
486
  status[4] = STATUS4;
487
  status[3] = STATUS3;
488
  status[2:0] = 3'bx; // these reserved bits are also unknown
489
 
490
  // There is no activity at this time
491
  status_read = 1'b0;
492
  updating_buffer1 = 1'b0;
493
  updating_buffer2 = 1'b0;
494
  updating_memory = 1'b0;
495
  comparing = 1'b0;
496
  erasing_page = 1'b0;
497
  erasing_block = 1'b0;
498
 
499
  // All o/ps are High-impedance
500
  SO_on = 1'b0;
501
  RDYBSY_reg = 1'b0;
502
 
503
end
504
 
505
 
506
always @(negedge CSB)  // the device will now become active
507
begin : get_opcode
508
   if (SCK == 1'b0)
509
   begin
510
      skip = 1'b1;
511
 
512
   end
513
   else
514
   begin
515
      skip = 1'b0;
516
      // If the opcode is related to SPI Mode 0/3, no skipping is needed. So, skip
517
      // will be reset to "0".
518
      // If opcode is related to Inactive Clock Low/high, skipping might or might
519
      // not be needed, depending on the value of SCK at negedge of CSB. So, in
520
      // such situations, skip will retain its value.
521
    end
522
 
523
   get_data;  // get opcode here
524
 
525
   case (status[5:3])
526
     3'b001:  // 1M Memory
527
         case (read_data)
528
           // Illegal Opcode for 1M memory. It has only one buffer.
529
           8'h56, 8'hd6, 8'h55, 8'h61, 8'h87, 8'h86, 8'h89, 8'h85, 8'h59:
530
              begin
531
                $display("Unrecognized opcode %h", read_data);
532
                disable get_opcode;
533
              end
534
         endcase
535
   endcase
536
 
537
   case (read_data)   // based on opcode, trigger an action
538
     8'h52 : -> MMPR ;  // Main Memory Page Read
539
     8'hd2 : begin
540
               skip = 1'b0;
541
               -> MMPR ;  // Main Memory Page Read
542
             end
543
     8'h54 : -> B1R ;   // Buffer 1 Read
544
     8'hd4 : begin
545
               skip = 1'b0;
546
               -> B1R ;   // Buffer 1 Read
547
             end
548
     8'h56 : -> B2R ;   // Buffer 2 Read
549
     8'hd6 : begin
550
               skip = 1'b0;
551
               -> B2R ;   // Buffer 2 Read
552
             end
553
     8'h53 : -> MMPTB1T ;   // Main Memory Page To Buffer 1 Transfer
554
     8'h55 : -> MMPTB2T ;   // Main Memory Page To Buffer 2 Transfer
555
     8'h60 : -> MMPTB1C ;   // Main Memory Page To Buffer 1 Compare
556
     8'h61 : -> MMPTB2C ;   // Main Memory Page To Buffer 2 Compare
557
     8'h84 : -> B1W ;   // Buffer 1 Write
558
     8'h87 : -> B2W ;   // Buffer 2 Write
559
     8'h83 : -> B1TMMPPWBIE ;   // Buffer 1 To Main Memory Page Prog 
560
                                               //With Built-In Erase 
561
     8'h86 : -> B2TMMPPWBIE ;   // Buffer 2 To Main Memory Page Prog 
562
                                               //With Built-In Erase 
563
     8'h88 : -> B1TMMPPWOBIE ;   // Buffer 1 To Main Memory Page Prog 
564
                                               //WithoOut Built-In Erase 
565
     8'h89 : -> B2TMMPPWOBIE ;   // Buffer 2 To Main Memory Page Prog 
566
                                               //WithoOut Built-In Erase 
567
     8'h81 : -> PE ;   // Page Erase
568
     8'h50 : -> BE ;   // Block Erase
569
     8'h82 : -> MMPPB1 ;   // Main Memory Page Prog. Through Buffer 1
570
     8'h85 : -> MMPPB2 ;   // Main Memory Page Prog. Through Buffer 2
571
     8'h58 : -> APRB1 ;   // Auto Page Rewrite Through Buffer 1
572
     8'h59 : -> APRB2 ;   // Auto Page Rewrite Through Buffer 2
573
     8'h57 : -> SR ;   // Status Register Read
574
     8'hd7 : begin
575
               skip = 1'b0;
576
               -> SR ;   // Status Register Read
577
             end
578
     8'h68 : -> RWOPR ;
579
     8'hE8 : begin
580
               skip = 1'b0;
581
               -> RWOPR ;
582
             end
583
     default : $display ("Unrecognized opcode %h", read_data);
584
   endcase
585
end
586
 
587
 
588
/******* Main Memory Page Read ********************/
589
 
590
always @(MMPR)
591
begin : MMPR_
592
   if (RDYBSY_reg == 1'b1) // device is already busy
593
   begin
594
     $display ("Device is busy. Main Memory Page Read is not allowed");
595
     disable MMPR_ ;
596
   end
597
         // if it comes here, means, the above if was false.
598
   get_data;
599
   temp_reg1[7:0] = read_data [7:0];
600
   get_data;
601
 
602
        // Now that the two byte_news have been obtained, distribute it 
603
        // within PageAddress and byte_new-address, according to 
604
        // the parameters.
605
   compute_page_address;
606
   compute_byte_new_address;
607
      // next 8 bits always contain byte_new-address[7:0], and, so is
608
      // not dependent on parameters
609
   get_data;
610
   byte_new[7:0] = read_data[7:0];
611
 
612
   for (j=0; j<4; j=j+1)
613
      get_data ;  // these 32 bits are dont-care, and so have been discarded.
614
 
615
   compute_address;
616
   if (skip == 1'b1)
617
     @(posedge SCK); // skip one SCK
618
   read_out (mem_no, current_address, page_boundary_low, page_boundary_high);
619
end
620
 
621
 
622
/******* Buffer 1 Read ********************/
623
 
624
always @(B1R)
625
begin : B1R_
626
   get_data; // first 8 bits are dont care
627
   get_data;
628
        // For buffers, PageAddress can be assumed as "0".
629
        // This will allow us to share code with MMPR;
630
   page [PADDRESS-1:0] = 'h0;
631
 
632
   compute_byte_new_address;
633
      // next 8 bits always contain byte_new-address[7:0], and, so is
634
      // not dependent on parameters
635
   get_data;
636
   byte_new[7:0] = read_data[7:0];
637
 
638
   compute_address;
639
   get_data; // next 8 bits are dont care
640
   if (skip == 1'b1)
641
     @(posedge SCK); // skip one SCK
642
   read_out (1, current_address, page_boundary_low, page_boundary_high);
643
end
644
 
645
 
646
 
647
/******* Buffer 2 Read ********************/
648
 
649
always @(B2R)
650
begin : B2R_
651
   get_data; // first 8 bits are dont care
652
   get_data;
653
        // For buffers, PageAddress can be assumed as "0".
654
        // This will allow us to share code with MMPR;
655
   page [PADDRESS-1:0] = 'h0;
656
 
657
   compute_byte_new_address;
658
 
659
      // next 8 bits always contain byte_new-address[7:0], and, so is
660
      // not dependent on parameters
661
   get_data;
662
   byte_new[7:0] = read_data[7:0];
663
 
664
   compute_address;
665
   get_data; // next 8 bits are don't care
666
   if (skip == 1'b1)
667
     @(posedge SCK); // skip one SCK
668
   read_out (2, current_address, page_boundary_low, page_boundary_high);
669
end
670
 
671
 
672
/******* Main Memory Page To Buffer 1 Transfer *****************/
673
 
674
always @(MMPTB1T)
675
begin : MMPTB1T_
676
   if (RDYBSY_reg == 1'b1) // device is already busy
677
   begin
678
     $display ("Device is busy. Main Memory To Buffer Transfer is not allowed");
679
     disable MMPTB1T_ ;
680
   end
681
         // if it comes here, means, the above if was false.
682
   get_data;
683
   temp_reg1[7:0] = read_data [7:0];
684
   get_data;
685
 
686
        // Now that the two byte_news have been obtained, distribute it 
687
        // within PageAddress according to the parameters
688
   compute_page_address;
689
 
690
   get_data; // This is dont_care
691
 
692
   compute_address; // even though, byte_new-address could be junk,
693
                    // we are only interested in Low page-boundaries,
694
                    // which can be obtained correctly
695
   @ (posedge CSB);
696
   RDYBSY_reg = 1'b1; // device is busy
697
   status[7] = 1'b0;
698
   transfer_to_buffer (1, page_boundary_low);
699
   updating_buffer1 = 1'b1;
700
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
701
   status[7] = 1'b1;
702
   updating_buffer1 = 1'b0;
703
end
704
 
705
 
706
/******* Main Memory Page To Buffer 2 Transfer *****************/
707
 
708
always @(MMPTB2T)
709
begin : MMPTB2T_
710
   if (RDYBSY_reg == 1'b1) // device is already busy
711
   begin
712
     $display ("Device is busy. Main Memory To Buffer Transfer is not allowed");
713
     disable MMPTB2T_ ;
714
   end
715
         // if it comes here, means, the above if was false.
716
   get_data;
717
   temp_reg1[7:0] = read_data [7:0];
718
   get_data;
719
 
720
        // Now that the two byte_news have been obtained, distribute it 
721
        // within PageAddress according to the parameters
722
   compute_page_address;
723
 
724
   get_data; // This is dont_care
725
 
726
   compute_address; // even though, byte_new-address could be junk,
727
                    // we are only interested in Low page-boundaries,
728
                    // which can be obtained correctly
729
   @ (posedge CSB);
730
   RDYBSY_reg = 1'b1; // device is busy
731
   status[7] = 1'b0;
732
   transfer_to_buffer (2, page_boundary_low);
733
   updating_buffer2 = 1'b1;
734
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
735
   status[7] = 1'b1;
736
   updating_buffer2 = 1'b0;
737
end
738
 
739
 
740
/******* Main Memory Page To Buffer 1 Compare *****************/
741
 
742
always @(MMPTB1C)
743
begin : MMPTB1C_
744
   if (RDYBSY_reg == 1'b1) // device is already busy
745
   begin
746
     $display ("Device is busy. Main Memory To Buffer Compare is not allowed");
747
     disable MMPTB1C_ ;
748
   end
749
         // if it comes here, means, the above if was false.
750
   get_data;
751
   temp_reg1[7:0] = read_data [7:0];
752
   get_data;
753
 
754
        // Now that the two byte_news have been obtained, distribute it 
755
        // within PageAddress according to the parameters
756
   compute_page_address;
757
 
758
   get_data; // This is dont_care
759
 
760
   compute_address; // even though, byte_new-address could be junk,
761
                    // we are only interested in Low page-boundaries,
762
                    // which can be obtained correctly
763
   @ (posedge CSB);
764
   RDYBSY_reg = 1'b1; // device is busy
765
   status[7] = 1'b0;
766
   compare_with_buffer (1, page_boundary_low);
767
   comparing = 1'b1;
768
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
769
   status[7] = 1'b1;
770
   comparing = 1'b0;
771
end
772
 
773
 
774
 
775
/******* Main Memory Page To Buffer 2 Compare *****************/
776
 
777
always @(MMPTB2C)
778
begin : MMPTB2C_
779
   if (RDYBSY_reg == 1'b1) // device is already busy
780
   begin
781
     $display ("Device is busy. Main Memory To Buffer Compare is not allowed");
782
     disable MMPTB2C_ ;
783
   end
784
         // if it comes here, means, the above if was false.
785
   get_data;
786
   temp_reg1[7:0] = read_data [7:0];
787
   get_data;
788
 
789
        // Now that the two byte_news have been obtained, distribute it 
790
        // within PageAddress according to the parameters
791
   compute_page_address;
792
 
793
   get_data; // This is dont_care
794
 
795
   compute_address; // even though, byte_new-address could be junk,
796
                    // we are only interested in Low page-boundaries,
797
                    // which can be obtained correctly
798
   @ (posedge CSB);
799
   RDYBSY_reg = 1'b1; // device is busy
800
   status[7] = 1'b0;
801
   compare_with_buffer (2, page_boundary_low);
802
   comparing = 1'b1;
803
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
804
   status[7] = 1'b1;
805
   comparing = 1'b0;
806
end
807
 
808
 
809
/*******    Buffer 1 Write *****************/
810
 
811
always @(B1W)
812
begin : B1W_
813
   get_data; // dont care bits
814
   get_data;
815
            // got some address bits, depending on device parameters
816
   compute_byte_new_address;
817
   get_data;
818
   byte_new[7:0] = read_data [7:0];
819
 
820
   page[PADDRESS-1:0] = 'h0; // buffer is equivalent to just one page
821
 
822
   compute_address;
823
 
824
   write_data (1);
825
 
826
end
827
 
828
 
829
/*******    Buffer 2 Write *****************/
830
 
831
always @(B2W)
832
begin : B2W_
833
   get_data; // dont care bits
834
   get_data;
835
            // got some address bits, depending on device parameters
836
   compute_byte_new_address;
837
   get_data;
838
   byte_new[7:0] = read_data [7:0];
839
 
840
   page[PADDRESS-1:0] = 'h0; // buffer is equivalent to just one page
841
 
842
   compute_address;
843
 
844
   write_data (2);
845
 
846
end
847
 
848
 
849
/******* Buffer 1 To Main Memory Page Prog With Built In Erase *******/
850
 
851
always @(B1TMMPPWBIE)
852
begin : B1TMMPPWBIE_
853
   if (RDYBSY_reg == 1'b1) // device is already busy
854
   begin
855
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
856
     disable B1TMMPPWBIE_ ;
857
   end
858
         // if it comes here, means, the above if was false.
859
   get_data;
860
   temp_reg1[7:0] = read_data [7:0];
861
   get_data;
862
 
863
        // Now that the two byte_news have been obtained, distribute it 
864
        // within PageAddress according to the parameters
865
   compute_page_address;
866
 
867
   get_data; // This is dont_care
868
 
869
   if ((WPB == 1'b0) && (page < PROTECTED))
870
   begin
871
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
872
     disable B1TMMPPWBIE_ ;
873
   end
874
 
875
   compute_address; // even though, byte_new-address could be junk,
876
                    // we are only interested in Low page-boundaries,
877
                    // which can be obtained correctly
878
   @ (posedge CSB);
879
   RDYBSY_reg = 1'b1; // device is busy
880
   status[7] = 1'b0;
881
   write_to_memory (1, page_boundary_low);
882
   updating_memory = 1'b1;
883
   #tEP RDYBSY_reg = 1'b0; // device is now ready
884
   status[7] = 1'b1;
885
   updating_memory = 1'b0;
886
end
887
 
888
 
889
/******* Buffer 2 To Main Memory Page Prog With Built In Erase *******/
890
 
891
always @(B2TMMPPWBIE)
892
begin : B2TMMPPWBIE_
893
   if (RDYBSY_reg == 1'b1) // device is already busy
894
   begin
895
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
896
     disable B2TMMPPWBIE_ ;
897
   end
898
         // if it comes here, means, the above if was false.
899
   get_data;
900
   temp_reg1[7:0] = read_data [7:0];
901
   get_data;
902
 
903
        // Now that the two byte_news have been obtained, distribute it 
904
        // within PageAddress according to the parameters
905
   compute_page_address;
906
 
907
   get_data; // This is dont_care
908
 
909
   if ((WPB == 1'b0) && (page < PROTECTED))
910
   begin
911
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
912
     disable B2TMMPPWBIE_ ;
913
   end
914
 
915
   compute_address; // even though, byte_new-address could be junk,
916
                    // we are only interested in Low page-boundaries,
917
                    // which can be obtained correctly
918
   @ (posedge CSB);
919
   RDYBSY_reg = 1'b1; // device is busy
920
   status[7] = 1'b0;
921
   write_to_memory (2, page_boundary_low);
922
   updating_memory = 1'b1;
923
   #tEP RDYBSY_reg = 1'b0; // device is now ready
924
   status[7] = 1'b1;
925
   updating_memory = 1'b0;
926
end
927
 
928
 
929
/******* Buffer 1 To Main Memory Page Prog WithOut Built In Erase *******/
930
 
931
always @(B1TMMPPWOBIE)
932
begin : B1TMMPPWOBIE_
933
   if (RDYBSY_reg == 1'b1) // device is already busy
934
   begin
935
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
936
     disable B1TMMPPWOBIE_ ;
937
   end
938
         // if it comes here, means, the above if was false.
939
   get_data;
940
   temp_reg1[7:0] = read_data [7:0];
941
   get_data;
942
 
943
        // Now that the two byte_news have been obtained, distribute it 
944
        // within PageAddress according to the parameters
945
   compute_page_address;
946
 
947
   get_data; // This is dont_care
948
 
949
   if ((WPB == 1'b0) && (page < PROTECTED))
950
   begin
951
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
952
     disable B1TMMPPWOBIE_ ;
953
   end
954
 
955
   compute_address; // even though, byte_new-address could be junk,
956
                    // we are only interested in Low page-boundaries,
957
                    // which can be obtained correctly
958
   @ (posedge CSB);
959
   if (page_status[page] == 1'b0) // page is already erased
960
   begin
961
      RDYBSY_reg = 1'b1; // device is busy
962
      status[7] = 1'b0;
963
      write_to_memory (1, page_boundary_low);
964
      updating_memory = 1'b1;
965
      #tP RDYBSY_reg = 1'b0; // device is now ready
966
      status[7] = 1'b1;
967
      updating_memory = 1'b0;
968
   end
969
   else
970
      $display ("Trying to write into Page %d which is not erased", page);
971
end
972
 
973
 
974
/******* Buffer 2 To Main Memory Page Prog WithOut Built In Erase *******/
975
 
976
always @(B2TMMPPWOBIE)
977
begin : B2TMMPPWOBIE_
978
   if (RDYBSY_reg == 1'b1) // device is already busy
979
   begin
980
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
981
     disable B2TMMPPWOBIE_ ;
982
   end
983
         // if it comes here, means, the above if was false.
984
   get_data;
985
   temp_reg1[7:0] = read_data [7:0];
986
   get_data;
987
 
988
        // Now that the two byte_news have been obtained, distribute it 
989
        // within PageAddress according to the parameters
990
   compute_page_address;
991
 
992
   get_data; // This is dont_care
993
 
994
   if ((WPB == 1'b0) && (page < PROTECTED))
995
   begin
996
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
997
     disable B2TMMPPWOBIE_ ;
998
   end
999
 
1000
   compute_address; // even though, byte_new-address could be junk,
1001
                    // we are only interested in Low page-boundaries,
1002
                    // which can be obtained correctly
1003
   @ (posedge CSB);
1004
   if (page_status[page] == 1'b0) // page is already erased
1005
   begin
1006
      RDYBSY_reg = 1'b1; // device is busy
1007
      status[7] = 1'b0;
1008
      updating_memory = 1'b1;
1009
      write_to_memory (2, page_boundary_low);
1010
      #tP RDYBSY_reg = 1'b0; // device is now ready
1011
      status[7] = 1'b1;
1012
      updating_memory = 1'b0;
1013
   end
1014
   else
1015
      $display ("Trying to write into Page %d which is not erased", page);
1016
end
1017
 
1018
 
1019
/******* Page Erase *******/
1020
 
1021
always @(PE)
1022
begin : PE_
1023
   if (RDYBSY_reg == 1'b1) // device is already busy
1024
   begin
1025
     $display ("Device is busy. Page Erase is not allowed");
1026
     disable PE_ ;
1027
   end
1028
         // if it comes here, means, the above if was false.
1029
   get_data;
1030
   temp_reg1[7:0] = read_data [7:0];
1031
   get_data;
1032
 
1033
        // Now that the two byte_news have been obtained, distribute it 
1034
        // within PageAddress according to the parameters
1035
   compute_page_address;
1036
 
1037
   get_data; // This is dont_care
1038
 
1039
   if ((WPB == 1'b0) && (page < PROTECTED))
1040
   begin
1041
     $display ("Cann't Erase: Page No. %d is Protected, becase WPB is Low", page);
1042
     disable PE_ ;
1043
   end
1044
 
1045
   compute_address; // even though, byte_new-address could be junk,
1046
                    // we are only interested in Low page-boundaries,
1047
                    // which can be obtained correctly
1048
   @ (posedge CSB);
1049
   RDYBSY_reg = 1'b1; // device is busy
1050
   status[7] = 1'b0;
1051
   erase_page ( page_boundary_low);
1052
   erasing_page = 1'b1;
1053
   #tPE RDYBSY_reg = 1'b0; // device is now ready
1054
   status[7] = 1'b1;
1055
   erasing_page = 1'b0;
1056
end
1057
 
1058
 
1059
/******* Block Erase *******/
1060
 
1061
always @(BE)
1062
begin : BE_
1063
   if (RDYBSY_reg == 1'b1) // device is already busy
1064
   begin
1065
     $display ("Device is busy. Block Erase is not allowed");
1066
     disable BE_ ;
1067
   end
1068
         // if it comes here, means, the above if was false.
1069
   get_data;
1070
   temp_reg1[7:0] = read_data [7:0];
1071
   get_data;
1072
 
1073
        // Now that the two byte_news have been obtained, distribute it 
1074
        // within PageAddress according to the parameters
1075
   compute_page_address;
1076
   page [2:0] = 3'h0; // lowest page of the block
1077
 
1078
   get_data; // This is dont_care
1079
 
1080
   if ((WPB == 1'b0) && (page < PROTECTED))
1081
   begin
1082
     $display ("Cann't Erase: Block starting at Page No. %d is Protected, becase WPB is Low", page);
1083
     disable BE_ ;
1084
   end
1085
 
1086
   compute_address; // even though, byte_new-address could be junk,
1087
                    // we are only interested in Low page-boundaries,
1088
                    // which can be obtained correctly
1089
   @ (posedge CSB);
1090
   RDYBSY_reg = 1'b1; // device is busy
1091
   status[7] = 1'b0;
1092
 
1093
   for (j=page_boundary_low; j<(page_boundary_low+8*PAGESIZE); j=j+PAGESIZE)
1094
      erase_page ( j ); // erase 8 pages, i.e. a block
1095
 
1096
   for (j=0; j<8; j=j+1) // erase_page will only change the status of one-page 
1097
     page_status[page+j] = 1'b0; // hence, changing the remaining ones explicitly
1098
 
1099
   erasing_block = 1'b1;
1100
   #tBE RDYBSY_reg = 1'b0; // device is now ready
1101
   status[7] = 1'b1;
1102
   erasing_block = 1'b0;
1103
end
1104
 
1105
/******* Main Memory Page Prog Through Buffer 1 *******/
1106
 
1107
always @(MMPPB1)
1108
begin : MMPPB1_
1109
   if (RDYBSY_reg == 1'b1) // device is already busy
1110
   begin
1111
     $display ("Device is busy. Main Memory Page Prog. is not allowed");
1112
     disable MMPPB1_ ;
1113
   end
1114
         // if it comes here, means, the above if was false.
1115
   get_data;
1116
   temp_reg1[7:0] = read_data [7:0];
1117
   get_data;
1118
        // Now that the two byte_news have been obtained, distribute it 
1119
        // within PageAddress/ByteAddress according to the parameters
1120
   compute_page_address;
1121
   compute_byte_new_address;
1122
   temp_reg2[7:0] = read_data [7:0];
1123
   get_data;
1124
   byte_new[7:0] = read_data[7:0];
1125
   temp_page = page; // page value has been stored for main memory page program
1126
 
1127
 
1128
   page[PADDRESS-1:0] = 'h0; // Buffer is 0 pages
1129
 
1130
   compute_address; // this computes where to write in buffer
1131
 
1132
   write_data (1); // this will write to buffer
1133
                   // it will proceed to next step, when, posedge of CSB.
1134
                   // This is complicated, and, hence, explained here:
1135
                   // At posedge of CSB, the write_data will get disabled.
1136
                   // At this time, writing to buffer needs to stop, and,
1137
                   // writing into memory should start.
1138
 
1139
   page[PADDRESS-1:0] = temp_page[PADDRESS-1:0]; // page address in Main Memory to which
1140
                                                 // data needs to be written
1141
   if ((WPB == 1'b0) && (page < PROTECTED))
1142
   begin
1143
     $display ("Cann't Write: Page No. %d is Protected, becase WPB is Low", page);
1144
     disable MMPPB1_ ;
1145
   end
1146
 
1147
   compute_address; // even if byte_new-address is junk, we only need Page_Low_Boundary
1148
 
1149
   RDYBSY_reg = 1'b1; // device is busy
1150
   status[7] = 1'b0;
1151
   write_to_memory (1, page_boundary_low);
1152
   updating_memory = 1'b1;
1153
   #tEP RDYBSY_reg = 1'b0; // device is now ready
1154
   status[7] = 1'b1;
1155
   updating_memory = 1'b0;
1156
end
1157
 
1158
 
1159
/******* Main Memory Page Prog Through Buffer 2 *******/
1160
 
1161
always @(MMPPB2)
1162
begin : MMPPB2_
1163
   if (RDYBSY_reg == 1'b1) // device is already busy
1164
   begin
1165
     $display ("Device is busy. Main Memory Page Prog. is not allowed");
1166
     disable MMPPB2_ ;
1167
   end
1168
         // if it comes here, means, the above if was false.
1169
   get_data;
1170
   temp_reg1[7:0] = read_data [7:0];
1171
   get_data;
1172
        // Now that the two byte_news have been obtained, distribute it 
1173
        // within PageAddress/ByteAddress according to the parameters
1174
   compute_page_address;
1175
   compute_byte_new_address;
1176
   temp_reg2[7:0] = read_data [7:0];
1177
   get_data;
1178
   // Third byte_new is always for byte_new address[7:0]
1179
   byte_new[7:0] = read_data[7:0];
1180
 
1181
   temp_page = page; // page value has been stored for main memory page program
1182
 
1183
   page[PADDRESS-1:0] = 'h0; // Buffer is 0 pages
1184
 
1185
   compute_address; // this computes where to write in buffer
1186
 
1187
   write_data (2); // this will write to buffer
1188
                   // it will proceed to next step, when, posedge of CSB.
1189
                   // This is complicated, and, hence, explained here:
1190
                   // At posedge of CSB, the write_data will get disabled.
1191
                   // At this time, writing to buffer needs to stop, and,
1192
                   // writing into memory should start.
1193
 
1194
   page[PADDRESS-1:0] = temp_page[PADDRESS-1:0]; // page address in Main Memory to which
1195
                                                 // data needs to be written
1196
   if ((WPB == 1'b0) && (page < PROTECTED))
1197
   begin
1198
     $display ("Cann't Write: Page No. %d is Protected, becase WPB is Low", page);
1199
     disable MMPPB2_ ;
1200
   end
1201
 
1202
   compute_address; // even if byte_new-address is junk, we only need Page_Low_Boundary
1203
 
1204
   RDYBSY_reg = 1'b1; // device is busy
1205
   status[7] = 1'b0;
1206
   write_to_memory (2, page_boundary_low);
1207
   updating_memory = 1'b1;
1208
   #tEP RDYBSY_reg = 1'b0; // device is now ready
1209
   status[7] = 1'b1;
1210
   updating_memory = 1'b0;
1211
end
1212
 
1213
 
1214
/******* Auto Page Rewrite Through Buffer 1 *****************/
1215
 
1216
always @(APRB1)
1217
begin : APRB1_
1218
   if (RDYBSY_reg == 1'b1) // device is already busy
1219
   begin
1220
     $display ("Device is busy. Auto Page Rewrite is not allowed");
1221
     disable APRB1_ ;
1222
   end
1223
         // if it comes here, means, the above if was false.
1224
   get_data;
1225
   temp_reg1[7:0] = read_data [7:0];
1226
   get_data;
1227
 
1228
        // Now that the two byte_news have been obtained, distribute it 
1229
        // within PageAddress according to the parameters
1230
   compute_page_address;
1231
 
1232
   get_data; // This is dont_care
1233
 
1234
   compute_address; // even though, byte_new-address could be junk,
1235
                    // we are only interested in Low page-boundaries,
1236
                    // which can be obtained correctly
1237
   @ (posedge CSB);
1238
   transfer_to_buffer (1, page_boundary_low);
1239
   updating_buffer1 = 1'b1;
1240
 
1241
   if ((WPB == 1'b0) && (page < PROTECTED))
1242
   begin
1243
     $display ("Cann't ReWrite: Page No. %d is Protected, becase WPB is Low", page);
1244
     #tEP updating_buffer1 = 1'b0;
1245
     disable APRB1_ ;
1246
   end
1247
 
1248
   updating_memory = 1'b1;
1249
   RDYBSY_reg = 1'b1; // device is busy
1250
   status[7] = 1'b0;
1251
   #tEP RDYBSY_reg = 1'b0; // device is now ready
1252
   status[7] = 1'b1;
1253
   updating_buffer1 = 1'b0;
1254
   updating_memory = 1'b0;
1255
   // NOTE:
1256
   // We dont need to rewrite the data back into main-memory, as the 
1257
   //        data is already available in the main-memory
1258
   // This task was exactly same as MMPTB1T, except the delay-value
1259
   //      We could have easily used the same code as MMPTB1T, using 
1260
   //      an if condition for delay-selection. However, still doing
1261
   //      this way, so that the code for each opcode is independent
1262
   //      of anything else.
1263
end
1264
 
1265
 
1266
/******* Auto Page Rewrite Through Buffer 2 *****************/
1267
 
1268
always @(APRB2)
1269
begin : APRB2_
1270
   if (RDYBSY_reg == 1'b1) // device is already busy
1271
   begin
1272
     $display ("Device is busy. Auto Page Rewrite is not allowed");
1273
     disable APRB2_ ;
1274
   end
1275
         // if it comes here, means, the above if was false.
1276
   get_data;
1277
   temp_reg1[7:0] = read_data [7:0];
1278
   get_data;
1279
 
1280
        // Now that the two byte_news have been obtained, distribute it 
1281
        // within PageAddress according to the parameters
1282
   compute_page_address;
1283
 
1284
   get_data; // This is dont_care
1285
 
1286
   compute_address; // even though, byte_new-address could be junk,
1287
                    // we are only interested in Low page-boundaries,
1288
                    // which can be obtained correctly
1289
   @ (posedge CSB);
1290
   transfer_to_buffer (2, page_boundary_low);
1291
   updating_buffer2 = 1'b1;
1292
 
1293
   if ((WPB == 1'b0) && (page < PROTECTED))
1294
   begin
1295
     $display ("Cann't ReWrite: Page No. %d is Protected, becase WPB is Low", page);
1296
     #tEP updating_buffer2 = 1'b0;
1297
     disable APRB2_ ;
1298
   end
1299
 
1300
   RDYBSY_reg = 1'b1; // device is busy
1301
   status[7] = 1'b0;
1302
   updating_memory = 1'b1;
1303
   #tEP RDYBSY_reg = 1'b0; // device is now ready
1304
   status[7] = 1'b1;
1305
   updating_buffer2 = 1'b0;
1306
   updating_memory = 1'b0;
1307
   // NOTE:
1308
   // We dont need to rewrite the data back into main-memory, as the 
1309
   //        data is already available in the main-memory
1310
   // This task was exactly same as MMPTB2T, except the delay-value
1311
   //      We could have easily used the same code as MMPTB2T, using 
1312
   //      an if condition for delay-selection. However, still doing
1313
   //      this way, so that the code for each opcode is independent
1314
   //      of anything else.
1315
end
1316
 
1317
 
1318
/********* Status Register Read ********************/
1319
 
1320
always @(SR)
1321
begin: SR_
1322
  status_read = 1'b1; // reading status_reg
1323
  j = 8;
1324
   if (skip == 1'b1)
1325
     @(posedge SCK); // skip one SCK
1326
  while (CSB == 1'b0)
1327
  begin
1328
    @(negedge SCK);
1329
    #tV ;
1330
    if (j > 0)
1331
       j = j-1;
1332
    else
1333
       j = 7;
1334
    SO_reg=status[j];
1335
    SO_on = 1'b1;
1336
    SO_reg = status[j];
1337
  end // output next bit on next falling edge of SCK
1338
  status_read = 1'b0; // status_reg read is over
1339
 
1340
end
1341
 
1342
always @(negedge RDYBSY_reg) // this block to take care of situations,
1343
                             // where status gets changed, while, it
1344
                             // is being read.
1345
                             // Applicable only in cases, where, device gets
1346
                             // ready, from busy.
1347
   if (status_read == 1'b1)
1348
      SO_reg = status[j];    // No harm, even if we have done this for other bits
1349
                             // of status_reg
1350
 
1351
 
1352
/******* Main Memory Continuous Read ********************/
1353
 
1354
always @(RWOPR)
1355
begin : RWOPR_
1356
   if (RDYBSY_reg == 1'b1) // device is already busy
1357
   begin
1358
     $display ("Device is busy. Main Memory Page Read is not allowed");
1359
     disable RWOPR_ ;
1360
   end
1361
         // if it comes here, means, the above if was false.
1362
   get_data;
1363
   temp_reg1[7:0] = read_data [7:0];
1364
   get_data;
1365
 
1366
        // Now that the two byte_news have been obtained, distribute it 
1367
        // within PageAddress and byte_new-address, according to 
1368
        // the parameters.
1369
   compute_page_address;
1370
   compute_byte_new_address;
1371
 
1372
      // next 8 bits always contain byte_new-address[7:0], and, so is
1373
      // not dependent on parameters
1374
   get_data;
1375
   byte_new[7:0] = read_data[7:0];
1376
 
1377
   for (j=0; j<4; j=j+1)
1378
      get_data ;  // these 32 bits are dont-care, and so have been discarded.
1379
 
1380
   compute_address;
1381
   if (skip == 1'b1)
1382
     @(posedge SCK); // skip one SCK
1383
   read_out_array ;
1384
end
1385
 
1386
 
1387
/******** Posedge CSB. Stop all reading, recvng. commands/addresses etc. *********/
1388
 
1389
always @(posedge CSB)
1390
begin
1391
  disable MMPR_; // MMPR will stop, if CSB goes high
1392
  disable RWOPR_; // RWOPR will stop, if CSB goes high
1393
 
1394
  disable B1R_; // B1R will stop, if CSB goes high
1395
 
1396
  disable B2R_; // B2R will stop, if CSB goes high
1397
 
1398
  disable B1W_; // B1W will stop, if CSB goes high
1399
 
1400
  disable B2W_; // B2W will stop, if CSB goes high
1401
 
1402
  disable SR_; // Status reading should stop.
1403
  status_read = 1'b0;
1404
 
1405
  disable read_out; // Stop reading, NOW
1406
  disable read_out_array;
1407
  disable get_data; // Stop data retrieval
1408
  disable write_data; // Stop writing to buffers, NOW
1409
 
1410
  #tDIS SO_on = 1'b0;  // SO is now in high-impedance
1411
end
1412
 
1413
 
1414
/******** RESETB asserted. ******************/
1415
 
1416
always @(negedge RESETB)
1417
begin
1418
                               // stop doing whatever you were doing
1419
  disable get_opcode;
1420
  disable MMPR_;
1421
  disable B1R_;
1422
  disable B2R_;
1423
  disable MMPTB1T_;
1424
  disable MMPTB2T_;
1425
  disable MMPTB1C_;
1426
  disable MMPTB2C_;
1427
  disable B1W_;
1428
  disable B2W_;
1429
  disable B1TMMPPWBIE_;
1430
  disable B2TMMPPWBIE_;
1431
  disable B1TMMPPWOBIE_;
1432
  disable B2TMMPPWOBIE_;
1433
  disable PE_;
1434
  disable BE_;
1435
  disable MMPPB1_;
1436
  disable MMPPB2_;
1437
  disable APRB1_;
1438
  disable APRB2_;
1439
                            // if you were in the middle of some prog. that part
1440
                            //                  is now unknown.
1441
  if (updating_buffer1 == 1'b1)
1442
  begin
1443
    $display("RESETB asserted, when, updating Buffer1. Corrupting Buffer1");
1444
    corrupt_buffer (1);
1445
    updating_buffer1 = 1'b0;
1446
  end
1447
 
1448
  if (updating_buffer2 == 1'b1)
1449
  begin
1450
    $display("RESETB asserted, when, updating Buffer2. Corrupting Buffer1");
1451
    corrupt_buffer (2);
1452
    updating_buffer2 = 1'b0;
1453
  end
1454
 
1455
  if (comparing == 1'b1)
1456
  begin
1457
    $display("RESETB asserted, when, comparing. Corrupting Status Bit 6");
1458
    status[6] = 1'bx; // unknown
1459
    comparing = 1'b0;
1460
  end
1461
 
1462
  if (updating_memory == 1'b1)
1463
  begin
1464
    $display("RESETB asserted, when, updating memory. Corrupting Memory Page");
1465
    corrupt_memory ;
1466
    updating_memory = 1'b0;
1467
  end
1468
 
1469
  if (erasing_page == 1'b1)
1470
  begin
1471
    $display("RESETB asserted, when, erasing page. Corrupting Memory Page");
1472
    corrupt_memory ;
1473
    erasing_page = 1'b0;
1474
  end
1475
 
1476
  if (erasing_block == 1'b1)
1477
  begin
1478
    $display("RESETB asserted, when, erasing block. Corrupting Memory Block");
1479
    corrupt_block ;
1480
    erasing_block = 1'b0;
1481
  end
1482
 
1483
 // SO also, needs to go to high-state, as well as the device needs to be Ready.
1484
 SO_on = 1'b0;
1485
 RDYBSY_reg = 1'b0;
1486
 
1487
end
1488
 
1489
 
1490
/************************ TASKS / FUNCTIONS **************************/
1491
 
1492
/* get_data is a task to get 8 bits of data. This data could be an opcode,
1493
address, data or anything. It just obtains 8 bits of data obtained on SI*/
1494
 
1495
task get_data;
1496
 
1497
integer i;
1498
 
1499
begin
1500
   for (i=7; i>=0; i = i-1)
1501
   begin
1502
      @(posedge SCK);
1503
      read_data[i] = SI;
1504
   end
1505
end
1506
 
1507
endtask
1508
 
1509
 
1510
/* compute_address is a task which to compute the current address,
1511
as well as obtain the page boundaries */
1512
 
1513
task compute_address;
1514
 
1515
begin
1516
  page_boundary_low = page * PAGESIZE;
1517
  page_boundary_high = page_boundary_low + (PAGESIZE - 1);
1518
  current_address = page_boundary_low + byte_new;
1519
  if (current_address < 540672)
1520
      mem_no = 10;
1521
  else if (current_address < 1081344)
1522
      mem_no = 11;
1523
  else if (current_address < 1622016)
1524
      mem_no = 12;
1525
  else if (current_address < 2162688)
1526
      mem_no = 13;
1527
  else if (current_address < 2703360)
1528
      mem_no = 14;
1529
  else if (current_address < 3244032)
1530
      mem_no = 15;
1531
  else if (current_address < 3784704)
1532
      mem_no = 16;
1533
  else mem_no = 17;
1534
end
1535
 
1536
endtask
1537
 
1538
/* read_out will read the output on SO pin. It can read contents of mainmemory, or,
1539
either of the two buffers */
1540
 
1541
task read_out ;
1542
input mem_type;
1543
input add;
1544
input low;
1545
input high;
1546
 
1547
integer mem_type;
1548
integer add;
1549
integer low;
1550
integer high;
1551
 
1552
integer i;
1553
 
1554
begin
1555
  if (mem_type == 1)
1556
     temp_reg1 = buffer1 [add];
1557
  else if (mem_type == 2)
1558
     temp_reg1 = buffer2 [add];
1559
 
1560
  else if (mem_type == 10)
1561
     temp_reg1 = memory0 [add];
1562
  else if (mem_type == 11)
1563
     temp_reg1 = memory1 [add];
1564
  else if (mem_type == 12)
1565
     temp_reg1 = memory2 [add];
1566
  else if (mem_type == 13)
1567
     temp_reg1 = memory3 [add];
1568
  else if (mem_type == 14)
1569
     temp_reg1 = memory4 [add];
1570
  else if (mem_type == 15)
1571
     temp_reg1 = memory5 [add];
1572
  else if (mem_type == 16)
1573
     temp_reg1 = memory6 [add];
1574
  else if (mem_type == 17)
1575
     temp_reg1 = memory7 [add];
1576
  else
1577
     $display ("Int Error 1. This message should never appear. Something is wrong");
1578
 
1579
   i = 7;
1580
   while (CSB == 1'b0) // continue transmitting, while, CSB is Low
1581
   begin : CONTINUE_READING
1582
      @(negedge SCK) ;
1583
      #tV SO_reg = temp_reg1[i];
1584
          SO_on = 1'b1;
1585
      if (i == 0)
1586
        begin
1587
          add = add + 1; // next byte_new
1588
          i = 7;
1589
          if (add > high)
1590
              add = low; // Page rollover
1591
 
1592
          if (mem_type == 1)
1593
             temp_reg1 = buffer1 [add];
1594
          else if (mem_type == 2)
1595
             temp_reg1 = buffer2 [add];
1596
 
1597
          else if (mem_type == 10)
1598
             temp_reg1 = memory0 [add];
1599
          else if (mem_type == 11)
1600
             temp_reg1 = memory1 [add];
1601
          else if (mem_type == 12)
1602
             temp_reg1 = memory2 [add];
1603
          else if (mem_type == 13)
1604
             temp_reg1 = memory3 [add];
1605
          else if (mem_type == 14)
1606
             temp_reg1 = memory4 [add];
1607
          else if (mem_type == 15)
1608
             temp_reg1 = memory5 [add];
1609
          else if (mem_type == 16)
1610
             temp_reg1 = memory6 [add];
1611
          else if (mem_type == 17)
1612
             temp_reg1 = memory7 [add];
1613
 
1614
        end
1615
      else
1616
        i = i - 1; // next bit
1617
 
1618
   end // reading over, because CSB has gone high
1619
end
1620
 
1621
endtask
1622
 
1623
/* task read_out_array is to read from main Memory, either in
1624
          Continuous Mode, or, in Burst Mode */
1625
 
1626
task read_out_array ;
1627
 
1628
integer i;
1629
integer temp_mem;
1630
integer temp_current;
1631
integer temp_high;
1632
integer temp_low;
1633
integer temp_add;
1634
 
1635
begin
1636
  temp_mem = mem_no;
1637
  temp_high = page_boundary_high;
1638
  temp_low = page_boundary_low;
1639
  temp_add = current_address;
1640
 
1641
  if (temp_mem == 10)
1642
     temp_reg1 = memory0 [temp_add];
1643
  else if (temp_mem == 11)
1644
     temp_reg1 = memory1 [temp_add];
1645
  else if (temp_mem == 12)
1646
     temp_reg1 = memory2 [temp_add];
1647
  else if (temp_mem == 13)
1648
     temp_reg1 = memory3 [temp_add];
1649
  else if (temp_mem == 14)
1650
     temp_reg1 = memory4 [temp_add];
1651
  else if (temp_mem == 15)
1652
     temp_reg1 = memory5 [temp_add];
1653
  else if (temp_mem == 16)
1654
     temp_reg1 = memory6 [temp_add];
1655
  else if (temp_mem == 17)
1656
     temp_reg1 = memory7 [temp_add];
1657
  else
1658
     $display ("Int Error 1. This message should never appear. Something is wrong");
1659
 
1660
   i = 7;
1661
   while (CSB == 1'b0) // continue transmitting, while, CSB is Low
1662
   begin : CONTINUE_READING
1663
      @(negedge SCK) ;
1664
      #tV SO_reg = temp_reg1[i];
1665
          SO_on = 1'b1;
1666
      if (i == 0)
1667
        begin
1668
          temp_add = temp_add + 1; // next byte_new
1669
          i = 7;
1670
          if (temp_add >= MEMSIZE)
1671
          begin
1672
              temp_add = 0; // Note that rollover occurs at end of memory,
1673
              temp_high = PAGESIZE - 1; // and not at the end of the page
1674
              temp_low = 0;
1675
          end
1676
          if (temp_add > temp_high) // going to next page
1677
          begin
1678
             temp_high = temp_high + PAGESIZE;
1679
             temp_low = temp_low + PAGESIZE;
1680
          end
1681
 
1682
          if (temp_add > 3784703)  // this block is a kludge to take
1683
             temp_mem = 17;        // care of multiple memory declarations
1684
          else if (temp_add > 3244031) // in the model, due to limitation
1685
             temp_mem = 16;            // of Verilog
1686
          else if (temp_add > 2703359)
1687
             temp_mem = 15;
1688
          else if (temp_add > 2162687)
1689
             temp_mem = 14;
1690
          else if (temp_add > 1622015)
1691
             temp_mem = 13;
1692
          else if (temp_add > 1081343)
1693
             temp_mem = 12;
1694
          else if (temp_add > 540671)
1695
             temp_mem = 11;
1696
          else temp_mem = 10;
1697
 
1698
          if (temp_mem == 10)
1699
             temp_reg1 = memory0 [temp_add];
1700
          else if (temp_mem == 11)
1701
             temp_reg1 = memory1 [temp_add];
1702
          else if (temp_mem == 12)
1703
             temp_reg1 = memory2 [temp_add];
1704
          else if (temp_mem == 13)
1705
             temp_reg1 = memory3 [temp_add];
1706
          else if (temp_mem == 14)
1707
             temp_reg1 = memory4 [temp_add];
1708
          else if (temp_mem == 15)
1709
             temp_reg1 = memory5 [temp_add];
1710
          else if (temp_mem == 16)
1711
             temp_reg1 = memory6 [temp_add];
1712
          else if (temp_mem == 17)
1713
             temp_reg1 = memory7 [temp_add];
1714
 
1715
        end
1716
      else
1717
        i = i - 1; // next bit
1718
   end // reading over, because CSB has gone high
1719
end
1720
 
1721
endtask
1722
 
1723
 
1724
/* transfer_to_buffer will transfer data into a buffer from a page of
1725
main memory */
1726
 
1727
/* transfer_to_buffer will transfer data into a buffer from a page of
1728
main memory */
1729
 
1730
task transfer_to_buffer ;
1731
input buf_type;
1732
input low;
1733
 
1734
integer buf_type;
1735
integer low;
1736
 
1737
integer i;
1738
 
1739
begin
1740
       // Intentionally written this way: i.e. the for loop is within all if.
1741
       // Writing in alternative way would cause shorter code, but, significant
1742
       // increase in simulation time.
1743
  if (buf_type == 1)
1744
  begin
1745
    if (mem_no == 10)
1746
       for (i=0 ; i < PAGESIZE; i = i+1)
1747
          buffer1[i] = memory0[low+i];
1748
    else if (mem_no == 11)
1749
       for (i=0 ; i < PAGESIZE; i = i+1)
1750
          buffer1[i] = memory1[low+i];
1751
    else if (mem_no == 12)
1752
       for (i=0 ; i < PAGESIZE; i = i+1)
1753
          buffer1[i] = memory2[low+i];
1754
    else if (mem_no == 13)
1755
       for (i=0 ; i < PAGESIZE; i = i+1)
1756
          buffer1[i] = memory3[low+i];
1757
    else if (mem_no == 14)
1758
       for (i=0 ; i < PAGESIZE; i = i+1)
1759
          buffer1[i] = memory4[low+i];
1760
    else if (mem_no == 15)
1761
       for (i=0 ; i < PAGESIZE; i = i+1)
1762
          buffer1[i] = memory5[low+i];
1763
    else if (mem_no == 16)
1764
       for (i=0 ; i < PAGESIZE; i = i+1)
1765
          buffer1[i] = memory6[low+i];
1766
    else if (mem_no == 17)
1767
       for (i=0 ; i < PAGESIZE; i = i+1)
1768
          buffer1[i] = memory7[low+i];
1769
    else $display ("Should Never reach here. Something is wrong");
1770
  end
1771
 
1772
  else if (buf_type == 2)
1773
  begin
1774
    if (mem_no == 10)
1775
       for (i=0 ; i < PAGESIZE; i = i+1)
1776
          buffer2[i] = memory0[low+i];
1777
    else if (mem_no == 11)
1778
       for (i=0 ; i < PAGESIZE; i = i+1)
1779
          buffer2[i] = memory1[low+i];
1780
    else if (mem_no == 12)
1781
       for (i=0 ; i < PAGESIZE; i = i+1)
1782
          buffer2[i] = memory2[low+i];
1783
    else if (mem_no == 13)
1784
       for (i=0 ; i < PAGESIZE; i = i+1)
1785
          buffer2[i] = memory3[low+i];
1786
    else if (mem_no == 14)
1787
       for (i=0 ; i < PAGESIZE; i = i+1)
1788
          buffer2[i] = memory4[low+i];
1789
    else if (mem_no == 15)
1790
       for (i=0 ; i < PAGESIZE; i = i+1)
1791
          buffer2[i] = memory5[low+i];
1792
    else if (mem_no == 16)
1793
       for (i=0 ; i < PAGESIZE; i = i+1)
1794
          buffer2[i] = memory6[low+i];
1795
    else if (mem_no == 17)
1796
       for (i=0 ; i < PAGESIZE; i = i+1)
1797
          buffer2[i] = memory7[low+i];
1798
    else $display ("Should Never reach here. Something is wrong");
1799
  end
1800
 
1801
  else
1802
     $display ("Int Error 2. This message should never appear. Something is wrong");
1803
 
1804
end
1805
 
1806
endtask
1807
 
1808
 
1809
/* compare_with_buffer will compare data into a buffer against a page of
1810
main memory */
1811
 
1812
task compare_with_buffer ;
1813
input buf_type;
1814
input low;
1815
 
1816
integer buf_type;
1817
integer low;
1818
 
1819
integer i, k;
1820
reg [7:0] tmp1, tmp2;
1821
 
1822
begin
1823
 
1824
  status[6] = 1'b0;
1825
  if (buf_type == 1)
1826
    for (i=0 ; i < PAGESIZE; i = i+1)
1827
    begin : LOOP1
1828
       if (mem_no == 10)
1829
          tmp1 = memory0[low+i];
1830
       else if (mem_no == 11)
1831
          tmp1 = memory1[low+i];
1832
       else if (mem_no == 12)
1833
          tmp1 = memory2[low+i];
1834
       else if (mem_no == 13)
1835
          tmp1 = memory3[low+i];
1836
       else if (mem_no == 14)
1837
          tmp1 = memory4[low+i];
1838
       else if (mem_no == 15)
1839
          tmp1 = memory5[low+i];
1840
       else if (mem_no == 16)
1841
          tmp1 = memory6[low+i];
1842
       else if (mem_no == 17)
1843
          tmp1 = memory7[low+i];
1844
       else $display ("should never reach here. Something went wrong");
1845
       tmp2 = buffer1[i];
1846
       for (k=0; k < 8; k = k+1)
1847
           if (tmp1[k] !== tmp2[k])
1848
           begin  // detected miscompare. No need for further comparison
1849
             status[6] = 1'b1;
1850
             disable LOOP1;
1851
           end
1852
    end
1853
  else if (buf_type == 2)
1854
    for (i=0 ; i < PAGESIZE; i = i+1)
1855
    begin : LOOP2
1856
       if (mem_no == 10)
1857
          tmp1 = memory0[low+i];
1858
       else if (mem_no == 11)
1859
          tmp1 = memory1[low+i];
1860
       else if (mem_no == 12)
1861
          tmp1 = memory2[low+i];
1862
       else if (mem_no == 13)
1863
          tmp1 = memory3[low+i];
1864
       else if (mem_no == 14)
1865
          tmp1 = memory4[low+i];
1866
       else if (mem_no == 15)
1867
          tmp1 = memory5[low+i];
1868
       else if (mem_no == 16)
1869
          tmp1 = memory6[low+i];
1870
       else if (mem_no == 17)
1871
          tmp1 = memory7[low+i];
1872
       else $display ("should never reach here. Something went wrong");
1873
       tmp2 = buffer2[i];
1874
       for (k=0; k < 8; k = k+1)
1875
           if (tmp1[k] !== tmp2[k])
1876
           begin  // detected miscompare. No need for further comparison
1877
             status[6] = 1'b1;
1878
             disable LOOP2;
1879
           end
1880
    end
1881
  else
1882
     $display ("Int error 3. This message should never appear. Something is wrong");
1883
 
1884
end
1885
 
1886
endtask
1887
 
1888
 
1889
/* write_data will gat data from SI, and, write into device */
1890
 
1891
task write_data ;
1892
input buf_type;
1893
 
1894
integer buf_type;
1895
 
1896
integer i;
1897
 
1898
begin
1899
 
1900
   while (CSB == 1'b0)
1901
   begin
1902
     for (i=7; i>=0; i=i-1)
1903
     begin
1904
       @(posedge SCK);
1905
       temp_reg1[i] = SI;
1906
     end // Complete byte_new recvd. Now transfer the byte_new to memory/buffer
1907
 
1908
   if (buf_type == 1)  // Buffer 1
1909
      buffer1[current_address] = temp_reg1;
1910
   else if (buf_type == 2) // Buffer 2
1911
      buffer2[current_address] = temp_reg1;
1912
   else
1913
     $display ("Int error 4. This message should never appear. Something is wrong");
1914
 
1915
   current_address = current_address + 1;
1916
   if (current_address > page_boundary_high)
1917
       current_address = page_boundary_low;
1918
 
1919
   end // continue writing. Note that parts of a byte_new will not be written.
1920
 
1921
end
1922
 
1923
endtask
1924
 
1925
 
1926
/* write_to_memory will transfer data from a buffer into a page of
1927
main memory */
1928
 
1929
task write_to_memory ;
1930
input buf_type;
1931
input low;
1932
 
1933
integer buf_type;
1934
integer low;
1935
 
1936
integer i;
1937
 
1938
begin
1939
 
1940
  if (buf_type == 1)
1941
  begin
1942
    if (mem_no == 10)
1943
       for (i=0 ; i < PAGESIZE; i = i+1)
1944
          memory0[low+i] = buffer1[i];
1945
    else if (mem_no == 11)
1946
       for (i=0 ; i < PAGESIZE; i = i+1)
1947
          memory1[low+i] = buffer1[i];
1948
    else if (mem_no == 12)
1949
       for (i=0 ; i < PAGESIZE; i = i+1)
1950
          memory2[low+i] = buffer1[i];
1951
    else if (mem_no == 13)
1952
       for (i=0 ; i < PAGESIZE; i = i+1)
1953
          memory3[low+i] = buffer1[i];
1954
    else if (mem_no == 14)
1955
       for (i=0 ; i < PAGESIZE; i = i+1)
1956
          memory4[low+i] = buffer1[i];
1957
    else if (mem_no == 15)
1958
       for (i=0 ; i < PAGESIZE; i = i+1)
1959
          memory5[low+i] = buffer1[i];
1960
    else if (mem_no == 16)
1961
       for (i=0 ; i < PAGESIZE; i = i+1)
1962
          memory6[low+i] = buffer1[i];
1963
    else if (mem_no == 17)
1964
       for (i=0 ; i < PAGESIZE; i = i+1)
1965
          memory7[low+i] = buffer1[i];
1966
    else $display ("should never reach here. Something is wrong");
1967
  end
1968
  else if (buf_type == 2)
1969
  begin
1970
    if (mem_no == 10)
1971
       for (i=0 ; i < PAGESIZE; i = i+1)
1972
          memory0[low+i] = buffer2[i];
1973
    else if (mem_no == 11)
1974
       for (i=0 ; i < PAGESIZE; i = i+1)
1975
          memory1[low+i] = buffer2[i];
1976
    else if (mem_no == 12)
1977
       for (i=0 ; i < PAGESIZE; i = i+1)
1978
          memory2[low+i] = buffer2[i];
1979
    else if (mem_no == 13)
1980
       for (i=0 ; i < PAGESIZE; i = i+1)
1981
          memory3[low+i] = buffer2[i];
1982
    else if (mem_no == 14)
1983
       for (i=0 ; i < PAGESIZE; i = i+1)
1984
          memory4[low+i] = buffer2[i];
1985
    else if (mem_no == 15)
1986
       for (i=0 ; i < PAGESIZE; i = i+1)
1987
          memory5[low+i] = buffer2[i];
1988
    else if (mem_no == 16)
1989
       for (i=0 ; i < PAGESIZE; i = i+1)
1990
          memory6[low+i] = buffer2[i];
1991
    else if (mem_no == 17)
1992
       for (i=0 ; i < PAGESIZE; i = i+1)
1993
          memory7[low+i] = buffer2[i];
1994
    else $display ("should never reach here. Something is wrong");
1995
  end
1996
  else
1997
    $display ("Int error 4. This message should never appear. Something is wrong");
1998
 
1999
   page_status[page] = 1'b1; // this page is now not erased
2000
end
2001
 
2002
endtask
2003
 
2004
 
2005
/* erase_page will erase a page of main memory */
2006
 
2007
task erase_page ;
2008
input low;
2009
 
2010
integer low;
2011
 
2012
integer i;
2013
 
2014
begin
2015
    if (mem_no == 10)
2016
       for (i=0 ; i < PAGESIZE; i = i+1)
2017
          memory0[low+i] = 8'hff;
2018
    else if (mem_no == 11)
2019
       for (i=0 ; i < PAGESIZE; i = i+1)
2020
          memory1[low+i] = 8'hff;
2021
    else if (mem_no == 12)
2022
       for (i=0 ; i < PAGESIZE; i = i+1)
2023
          memory2[low+i] = 8'hff;
2024
    else if (mem_no == 13)
2025
       for (i=0 ; i < PAGESIZE; i = i+1)
2026
          memory3[low+i] = 8'hff;
2027
    else if (mem_no == 14)
2028
       for (i=0 ; i < PAGESIZE; i = i+1)
2029
          memory4[low+i] = 8'hff;
2030
    else if (mem_no == 15)
2031
       for (i=0 ; i < PAGESIZE; i = i+1)
2032
          memory5[low+i] = 8'hff;
2033
    else if (mem_no == 16)
2034
       for (i=0 ; i < PAGESIZE; i = i+1)
2035
          memory6[low+i] = 8'hff;
2036
    else if (mem_no == 17)
2037
       for (i=0 ; i < PAGESIZE; i = i+1)
2038
          memory7[low+i] = 8'hff;
2039
    else $display ("should never reach here. Something is wrong");
2040
 
2041
   page_status[page] = 1'b0; // this page is now erased
2042
end
2043
 
2044
endtask
2045
 
2046
 
2047
/* corrupt_buffer will corrupt the entire buffer */
2048
 
2049
task corrupt_buffer ;
2050
input buf_type;
2051
 
2052
integer buf_type;
2053
 
2054
integer i;
2055
 
2056
begin
2057
 
2058
  if (buf_type == 1)
2059
    for (i=0 ; i < PAGESIZE; i = i+1)
2060
       buffer1[i] = 8'hx;
2061
  else if (buf_type == 2)
2062
    for (i=0 ; i < PAGESIZE; i = i+1)
2063
       buffer2[i] = 8'hx;
2064
  else
2065
     $display ("Int Error 2. This message should never appear. Something is wrong");
2066
 
2067
end
2068
 
2069
endtask
2070
 
2071
 
2072
/* corrupt_memory will corrupt a page of memory */
2073
 
2074
task corrupt_memory ;
2075
 
2076
integer i;
2077
 
2078
begin
2079
    if (mem_no == 10)
2080
       for (i=0 ; i < PAGESIZE; i = i+1)
2081
          memory0[page_boundary_low+i] = 8'hx;
2082
    else if (mem_no == 11)
2083
       for (i=0 ; i < PAGESIZE; i = i+1)
2084
          memory1[page_boundary_low+i] = 8'hx;
2085
    else if (mem_no == 12)
2086
       for (i=0 ; i < PAGESIZE; i = i+1)
2087
          memory2[page_boundary_low+i] = 8'hx;
2088
    else if (mem_no == 13)
2089
       for (i=0 ; i < PAGESIZE; i = i+1)
2090
          memory3[page_boundary_low+i] = 8'hx;
2091
    else if (mem_no == 14)
2092
       for (i=0 ; i < PAGESIZE; i = i+1)
2093
          memory4[page_boundary_low+i] = 8'hx;
2094
    else if (mem_no == 15)
2095
       for (i=0 ; i < PAGESIZE; i = i+1)
2096
          memory5[page_boundary_low+i] = 8'hx;
2097
    else if (mem_no == 16)
2098
       for (i=0 ; i < PAGESIZE; i = i+1)
2099
          memory6[page_boundary_low+i] = 8'hx;
2100
    else if (mem_no == 17)
2101
       for (i=0 ; i < PAGESIZE; i = i+1)
2102
          memory7[page_boundary_low+i] = 8'hx;
2103
    else $display ("should never reach here. something is wrong");
2104
 
2105
   page_status[page] = 1'b1; // Actually, sometimes, the status of this page is
2106
                             // unknown. But, using UnErased, is also OK here.
2107
                             // Because, either way, user has to erase, in order
2108
                             // to Program the page
2109
end
2110
 
2111
endtask
2112
 
2113
 
2114
/* corrupt_block will corrupt a block (i.e. 8 pages) of memory */
2115
 
2116
task corrupt_block ;
2117
 
2118
integer i;
2119
 
2120
begin
2121
    if (mem_no == 10)
2122
       for (i=0 ; i < PAGESIZE*8; i = i+1)
2123
          memory0[page_boundary_low+i] = 8'hx; // corrupted 8 pages
2124
    else if (mem_no == 11)
2125
       for (i=0 ; i < PAGESIZE*8; i = i+1)
2126
          memory1[page_boundary_low+i] = 8'hx; // corrupted 8 pages
2127
    else if (mem_no == 12)
2128
       for (i=0 ; i < PAGESIZE*8; i = i+1)
2129
          memory2[page_boundary_low+i] = 8'hx; // corrupted 8 pages
2130
    else if (mem_no == 13)
2131
       for (i=0 ; i < PAGESIZE*8; i = i+1)
2132
          memory3[page_boundary_low+i] = 8'hx; // corrupted 8 pages
2133
    else if (mem_no == 14)
2134
       for (i=0 ; i < PAGESIZE*8; i = i+1)
2135
          memory4[page_boundary_low+i] = 8'hx; // corrupted 8 pages
2136
    else if (mem_no == 15)
2137
       for (i=0 ; i < PAGESIZE*8; i = i+1)
2138
          memory5[page_boundary_low+i] = 8'hx; // corrupted 8 pages
2139
    else if (mem_no == 16)
2140
       for (i=0 ; i < PAGESIZE*8; i = i+1)
2141
          memory6[page_boundary_low+i] = 8'hx; // corrupted 8 pages
2142
    else if (mem_no == 17)
2143
       for (i=0 ; i < PAGESIZE*8; i = i+1)
2144
          memory7[page_boundary_low+i] = 8'hx; // corrupted 8 pages
2145
    else $display ("should never reach here. Something is wrong");
2146
 
2147
    for (i=0 ; i < 8; i = i+1)
2148
       page_status[page+i] = 1'b1; // Actually, sometimes, the status of this page is
2149
                                   //   unknown. But, using UnErased, is also OK here.
2150
                                   //   Because, either way, user has to erase, in order
2151
                                   //   to Program the page
2152
end
2153
 
2154
endtask
2155
 
2156
 
2157
/* Task to compute page address */
2158
 
2159
task compute_page_address;
2160
begin
2161
   page = 0; // zero out the redundant bits of 'page'
2162
   case (PADDRESS)
2163
      13 : begin
2164
             page [12:6] = temp_reg1[6:0] ;
2165
             page [5:0] = read_data[7:2] ;
2166
           end
2167
      12 : begin
2168
             if (status[5:3] == 3'b100)
2169
             begin
2170
               page [11:7] = temp_reg1[4:0] ;
2171
               page [6:0] = read_data[7:1] ;
2172
             end
2173
             if (status[5:3] == 3'b101)
2174
             begin
2175
               page [11:6] = temp_reg1[5:0] ;
2176
               page [5:0] = read_data[7:2] ;
2177
             end
2178
           end
2179
      11 : begin
2180
             page [10:7] = temp_reg1[3:0] ;
2181
             page [6:0] = read_data[7:1] ;
2182
           end
2183
      10 : begin
2184
             page [9:7] = temp_reg1[2:0] ;
2185
             page [6:0] = read_data[7:1] ;
2186
           end
2187
       9 : begin
2188
             page [8:7] = temp_reg1[1:0] ;
2189
             page [6:0] = read_data[7:1] ;
2190
           end
2191
   endcase
2192
end
2193
endtask
2194
 
2195
/* Task to compute starting byte_new address */
2196
 
2197
task compute_byte_new_address;
2198
begin
2199
   case (BADDRESS)
2200
      10 : byte_new[9:8] = read_data[1:0] ;
2201
       9 : byte_new[8]   = read_data[0] ;
2202
   endcase
2203
end
2204
endtask
2205
 
2206
/* SPECIFY BLOCK */
2207
 
2208
specify  /* all timing checks */
2209
 
2210
`ifdef device1M
2211
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
2212
specparam tWH = 35;
2213
specparam tWL = 35;
2214
specparam tCS = 250;
2215
specparam tCSS = 250;
2216
specparam tCSH = 250;
2217
specparam tCSB = 200;
2218
specparam tSU = 10;
2219
specparam tH = 20;
2220
specparam tHO = 0;
2221
specparam tRST = 10000;
2222
specparam tREC = 1000;
2223
specparam tBAR = 200;
2224
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
2225
specparam tBRBD = 1000;
2226
`endif
2227
 
2228
`ifdef device2M
2229
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
2230
specparam tWH = 35;
2231
specparam tWL = 35;
2232
specparam tCS = 250;
2233
specparam tCSS = 250;
2234
specparam tCSH = 250;
2235
specparam tCSB = 200;
2236
specparam tSU = 10;
2237
specparam tH = 20;
2238
specparam tHO = 0;
2239
specparam tRST = 10000;
2240
specparam tREC = 1000;
2241
specparam tBAR = 200;
2242
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
2243
specparam tBRBD = 1000;
2244
`endif
2245
 
2246
`ifdef device4M
2247
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
2248
specparam tWH = 35;
2249
specparam tWL = 35;
2250
specparam tCS = 250;
2251
specparam tCSS = 250;
2252
specparam tCSH = 250;
2253
specparam tCSB = 200;
2254
specparam tSU = 10;
2255
specparam tH = 20;
2256
specparam tHO = 0;
2257
specparam tRST = 10000;
2258
specparam tREC = 1000;
2259
specparam tBAR = 200;
2260
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
2261
specparam tBRBD = 1000;
2262
`endif
2263
 
2264
`ifdef device8M
2265
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
2266
specparam tWH = 35;
2267
specparam tWL = 35;
2268
specparam tCS = 250;
2269
specparam tCSS = 250;
2270
specparam tCSH = 250;
2271
specparam tCSB = 200;
2272
specparam tSU = 10;
2273
specparam tH = 20;
2274
specparam tHO = 0;
2275
specparam tRST = 10000;
2276
specparam tREC = 1000;
2277
specparam tBAR = 200;
2278
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
2279
specparam tBRBD = 1000;
2280
`endif
2281
 
2282
`ifdef device16M
2283
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
2284
specparam tWH = 35;
2285
specparam tWL = 35;
2286
specparam tCS = 250;
2287
specparam tCSS = 250;
2288
specparam tCSH = 250;
2289
specparam tCSB = 200;
2290
specparam tSU = 10;
2291
specparam tH = 20;
2292
specparam tHO = 0;
2293
specparam tRST = 10000;
2294
specparam tREC = 1000;
2295
specparam tBAR = 200;
2296
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
2297
specparam tBRBD = 1000;
2298
`endif
2299
 
2300
`ifdef device32M
2301
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
2302
specparam tWH = 35;
2303
specparam tWL = 35;
2304
specparam tCS = 250;
2305
specparam tCSS = 250;
2306
specparam tCSH = 250;
2307
specparam tCSB = 200;
2308
specparam tSU = 10;
2309
specparam tH = 20;
2310
specparam tHO = 0;
2311
specparam tRST = 10000;
2312
specparam tREC = 1000;
2313
specparam tBAR = 200;
2314
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
2315
specparam tBRBD = 1000;
2316
`endif
2317
 
2318
  // SCK related
2319
  $period(posedge SCK, tSCK); // SCK period is checked between
2320
  $period(negedge SCK, tSCK); // rise-to-rise, as well as fall-to-fall
2321
  $width(posedge SCK, tWH); // High PulseWidth
2322
  $width(negedge SCK, tWL); // Low PulseWidth
2323
 
2324
  // CSB related
2325
  $width(posedge CSB, tCS); // CSB Min. High
2326
  $setup(CSB,posedge SCK, tCSS); // CSB setup time
2327
  $hold(posedge SCK, CSB, tCSH); // CSB hold time
2328
 
2329
  // SI related. Being checked, only when CSB is Low
2330
   $setup(SI, posedge SCK &&& ~CSB, tSU); // SI setup time
2331
   $hold(posedge SCK &&& ~CSB, SI, tH); // SI hold time
2332
 
2333
  // RESETB related
2334
  $width(negedge RESETB, tRST); // RESETB Low Width
2335
  $recovery(posedge SCK, RESETB, tREC); // RESETB Recovery 
2336
 
2337
endspecify
2338
 
2339
endmodule
2340
 
2341
//`include "test_sequence2.v"

powered by: WebSVN 2.1.0

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