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 15

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

powered by: WebSVN 2.1.0

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