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

Subversion Repositories turbo8051

[/] [turbo8051/] [trunk/] [verif/] [agents/] [spi/] [atmel/] [AT45DBXXX_v2.0.3.v] - Diff between revs 15 and 76

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 15 Rev 76
/************************************************************************
/************************************************************************
 
 
        Verilog model for Atmel Devices
        Verilog model for Atmel Devices
          AT45DBXXX  parameterizable
          AT45DBXXX  parameterizable
 
 
            Developed for Atmel By:
            Developed for Atmel By:
                Jason G Brown
                Jason G Brown
                Glenn Donovan
                Glenn Donovan
                 Jeff Gladu
                 Jeff Gladu
 
 
              January 24, 2002
              January 24, 2002
 
 
************************************************************************/
************************************************************************/
 
 
/************************************************************************
/************************************************************************
Development History:
Development History:
 
 
  AT45DBXXX model : Sanjay Churiwala, May-June 1999
  AT45DBXXX model : Sanjay Churiwala, May-June 1999
  Parameterized   : Niranjan Vaish, June 1999
  Parameterized   : Niranjan Vaish, June 1999
 
 
Revision History:
Revision History:
 
 
1.0    : Niranjan Vaish   : Parametrized model for AT45DBXXX devices.
1.0    : Niranjan Vaish   : Parametrized model for AT45DBXXX devices.
1.1    : Niranjan Vaish   : Updated RDY_BUSYB driving register.
1.1    : Niranjan Vaish   : Updated RDY_BUSYB driving register.
2.0    : Niranjan Vaish   : 2M, 4M and 8M also offer Page Erase and Block Erase.
2.0    : Niranjan Vaish   : 2M, 4M and 8M also offer Page Erase and Block Erase.
2.0.1  : Niranjan Vaish   : buffer1 and buffer2 were not declared correctly.
2.0.1  : Niranjan Vaish   : buffer1 and buffer2 were not declared correctly.
2.0.2  : Niranjan Vaish   : Additional parametrization has been done.
2.0.2  : Niranjan Vaish   : Additional parametrization has been done.
2.0.3  : WPI Project Team : Removed Burst Mode.
2.0.3  : WPI Project Team : Removed Burst Mode.
 
 
*************************************************************************/
*************************************************************************/
 
 
 
 
/*************************************************************************
/*************************************************************************
 Define the configuration which you want to use.
 Define the configuration which you want to use.
*************************************************************************/
*************************************************************************/
//`define device4M 1  // This model will work like AT45DB041
//`define device4M 1  // This model will work like AT45DB041
`define device32M 1  // This model will work like AT45DB321
`define device32M 1  // This model will work like AT45DB321
 
 
 
 
/*************************************************************************/
/*************************************************************************/
`timescale 1ns / 10ps
 
 
 
`ifdef device1M
`ifdef device1M
module AT45DB011 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
module AT45DB011 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
`endif
`endif
 
 
`ifdef device2M
`ifdef device2M
module AT45DB021 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
module AT45DB021 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
`endif
`endif
 
 
`ifdef device4M
`ifdef device4M
module AT45DB041 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
module AT45DB041 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
`endif
`endif
 
 
`ifdef device8M
`ifdef device8M
module AT45DB081 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
module AT45DB081 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
`endif
`endif
 
 
`ifdef device16M
`ifdef device16M
module AT45DB161 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
module AT45DB161 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
`endif
`endif
 
 
`ifdef device32M
`ifdef device32M
module AT45DB321 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
module AT45DB321 (CSB, SCK, SI, WPB, RESETB, RDY_BUSYB, SO);
`endif
`endif
 
 
input CSB, SCK, SI, WPB, RESETB;
input CSB, SCK, SI, WPB, RESETB;
output SO, RDY_BUSYB;
output SO, RDY_BUSYB;
 
 
/*************************************************************************
/*************************************************************************
Device configuration parameters :
Device configuration parameters :
*************************************************************************/
*************************************************************************/
 
 
`ifdef device1M
`ifdef device1M
parameter DEVICE = "AT45DB011";
parameter DEVICE = "AT45DB011";
parameter MEMSIZE = 135168; // no of byte_news = PAGESIZE * PAGES
parameter MEMSIZE = 135168; // no of byte_news = PAGESIZE * PAGES
parameter PAGESIZE = 264; // no of byte_news per page
parameter PAGESIZE = 264; // no of byte_news per page
parameter PAGES = 512; // no of pages
parameter PAGES = 512; // no of pages
parameter STATUS3 = 1;  // this and next two lines are for
parameter STATUS3 = 1;  // this and next two lines are for
                               //bits 3 to 5 of status register
                               //bits 3 to 5 of status register
parameter STATUS4 = 0;
parameter STATUS4 = 0;
parameter STATUS5 = 0;
parameter STATUS5 = 0;
parameter BUFFERS = 1; // no. of buffers
parameter BUFFERS = 1; // no. of buffers
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
parameter PADDRESS = 9; // no of bits needed to access a page
parameter PADDRESS = 9; // no of bits needed to access a page
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
`endif
`endif
 
 
`ifdef device2M
`ifdef device2M
parameter DEVICE = "AT45DB021";
parameter DEVICE = "AT45DB021";
parameter MEMSIZE = 270336; // no of byte_news = PAGESIZE * PAGES
parameter MEMSIZE = 270336; // no of byte_news = PAGESIZE * PAGES
parameter PAGESIZE = 264; // no of byte_news per page
parameter PAGESIZE = 264; // no of byte_news per page
parameter PAGES = 1024; // no of pages
parameter PAGES = 1024; // no of pages
parameter STATUS3 = 0;  // this and next two lines are for
parameter STATUS3 = 0;  // this and next two lines are for
                               //bits 3 to 5 of status register
                               //bits 3 to 5 of status register
parameter STATUS4 = 1;
parameter STATUS4 = 1;
parameter STATUS5 = 0;
parameter STATUS5 = 0;
parameter BUFFERS = 2; // no. of buffers
parameter BUFFERS = 2; // no. of buffers
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
parameter PADDRESS = 10; // no of bits needed to access a page
parameter PADDRESS = 10; // no of bits needed to access a page
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
`endif
`endif
 
 
`ifdef device4M
`ifdef device4M
parameter DEVICE = "AT45DB041";
parameter DEVICE = "AT45DB041";
parameter MEMSIZE = 540672; // no of byte_news = PAGESIZE * PAGES
parameter MEMSIZE = 540672; // no of byte_news = PAGESIZE * PAGES
parameter PAGESIZE = 264; // no of byte_news per page
parameter PAGESIZE = 264; // no of byte_news per page
parameter PAGES = 2048; // no of pages
parameter PAGES = 2048; // no of pages
parameter STATUS3 = 1;  // this and next two lines are for
parameter STATUS3 = 1;  // this and next two lines are for
                               //bits 3 to 5 of status register
                               //bits 3 to 5 of status register
parameter STATUS4 = 1;
parameter STATUS4 = 1;
parameter STATUS5 = 0;
parameter STATUS5 = 0;
parameter BUFFERS = 2; // no. of buffers
parameter BUFFERS = 2; // no. of buffers
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
parameter PADDRESS = 11; // no of bits needed to access a page
parameter PADDRESS = 11; // no of bits needed to access a page
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
`endif
`endif
 
 
`ifdef device8M
`ifdef device8M
parameter DEVICE = "AT45DB081";
parameter DEVICE = "AT45DB081";
parameter MEMSIZE = 1081344; // no of byte_news = PAGESIZE * PAGES
parameter MEMSIZE = 1081344; // no of byte_news = PAGESIZE * PAGES
parameter PAGESIZE = 264; // no of byte_news per page
parameter PAGESIZE = 264; // no of byte_news per page
parameter PAGES = 4096; // no of pages
parameter PAGES = 4096; // no of pages
parameter STATUS3 = 0;  // this and next two lines are for
parameter STATUS3 = 0;  // this and next two lines are for
                               //bits 3 to 5 of status register
                               //bits 3 to 5 of status register
parameter STATUS4 = 0;
parameter STATUS4 = 0;
parameter STATUS5 = 1;
parameter STATUS5 = 1;
parameter BUFFERS = 2; // no. of buffers
parameter BUFFERS = 2; // no. of buffers
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
parameter BADDRESS = 9; // no of bits needed to access a byte_new within a page
parameter PADDRESS = 12; // no of bits needed to access a page
parameter PADDRESS = 12; // no of bits needed to access a page
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
`endif
`endif
 
 
`ifdef device16M
`ifdef device16M
parameter DEVICE = "AT45DB161";
parameter DEVICE = "AT45DB161";
parameter MEMSIZE = 2162688; // no of byte_news = PAGESIZE * PAGES
parameter MEMSIZE = 2162688; // no of byte_news = PAGESIZE * PAGES
parameter PAGESIZE = 528; // no of byte_news per page
parameter PAGESIZE = 528; // no of byte_news per page
parameter PAGES = 4096; // no of pages
parameter PAGES = 4096; // no of pages
parameter STATUS3 = 1;  // this and next two lines are for
parameter STATUS3 = 1;  // this and next two lines are for
                               //bits 3 to 5 of status register
                               //bits 3 to 5 of status register
parameter STATUS4 = 0;
parameter STATUS4 = 0;
parameter STATUS5 = 1;
parameter STATUS5 = 1;
parameter BUFFERS = 2; // no. of buffers
parameter BUFFERS = 2; // no. of buffers
parameter BADDRESS = 10; // no of bits needed to access a byte_new within a page
parameter BADDRESS = 10; // no of bits needed to access a byte_new within a page
parameter PADDRESS = 12; // no of bits needed to access a page
parameter PADDRESS = 12; // no of bits needed to access a page
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
`endif
`endif
 
 
 
 
 
 
`ifdef device32M
`ifdef device32M
parameter DEVICE = "AT45DB321";
parameter DEVICE = "AT45DB321";
//parameter MEMSIZE = 4194304; // no of byte_news = PAGESIZE * PAGES
//parameter MEMSIZE = 4194304; // no of byte_news = PAGESIZE * PAGES
parameter MEMSIZE = 4325376; // no of byte_news = PAGESIZE * PAGES
parameter MEMSIZE = 4325376; // no of byte_news = PAGESIZE * PAGES
parameter PAGESIZE = 528; // no of byte_news per page
parameter PAGESIZE = 528; // no of byte_news per page
parameter PAGES = 8192; // no of pages
parameter PAGES = 8192; // no of pages
parameter STATUS3 = 0;  // this and next two lines are for 
parameter STATUS3 = 0;  // this and next two lines are for 
                               //bits 3 to 5 of status register
                               //bits 3 to 5 of status register
parameter STATUS4 = 1;
parameter STATUS4 = 1;
parameter STATUS5 = 1;
parameter STATUS5 = 1;
parameter BUFFERS = 2; // no. of buffers
parameter BUFFERS = 2; // no. of buffers
parameter BADDRESS = 10; // no of bits needed to access a byte_new within a page
parameter BADDRESS = 10; // no of bits needed to access a byte_new within a page
parameter PADDRESS = 13; // no of bits needed to access a page
parameter PADDRESS = 13; // no of bits needed to access a page
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
parameter PROTECTED = 256; // no of pages that can be Protected, using WPB
`endif
`endif
 
 
/********************************************************************
/********************************************************************
Timing Parameters :
Timing Parameters :
More timing parameters given as specparam within the specify block
More timing parameters given as specparam within the specify block
********************************************************************/
********************************************************************/
 
 
`ifdef device1M
`ifdef device1M
parameter tDIS = 25;
parameter tDIS = 25;
parameter tV = 30;
parameter tV = 30;
parameter tXFR = 200000;
parameter tXFR = 200000;
parameter tEP = 20000000;
parameter tEP = 20000000;
parameter tP = 15000000;
parameter tP = 15000000;
parameter tPE = 10000000;
parameter tPE = 10000000;
parameter tBE = 15000000;
parameter tBE = 15000000;
parameter tCAR = 200;
parameter tCAR = 200;
`endif
`endif
 
 
`ifdef device2M
`ifdef device2M
parameter tDIS = 25;
parameter tDIS = 25;
parameter tV = 30;
parameter tV = 30;
parameter tXFR = 250000;
parameter tXFR = 250000;
parameter tEP = 20000000;
parameter tEP = 20000000;
parameter tP = 14000000;
parameter tP = 14000000;
parameter tPE = 10000000; // Correct it
parameter tPE = 10000000; // Correct it
parameter tBE = 15000000; // Correct it
parameter tBE = 15000000; // Correct it
parameter tCAR = 200;
parameter tCAR = 200;
`endif
`endif
 
 
`ifdef device4M
`ifdef device4M
parameter tDIS = 25;
parameter tDIS = 25;
parameter tV = 30;
parameter tV = 30;
parameter tXFR = 250000;
parameter tXFR = 250000;
parameter tEP = 20000000;
parameter tEP = 20000000;
parameter tP = 14000000;
parameter tP = 14000000;
parameter tPE = 10000000;
parameter tPE = 10000000;
parameter tBE = 15000000;
parameter tBE = 15000000;
parameter tCAR = 200;
parameter tCAR = 200;
`endif
`endif
 
 
`ifdef device8M
`ifdef device8M
parameter tDIS = 25;
parameter tDIS = 25;
parameter tV = 30;
parameter tV = 30;
parameter tXFR = 200000;
parameter tXFR = 200000;
parameter tEP = 20000000;
parameter tEP = 20000000;
parameter tP = 14000000;
parameter tP = 14000000;
parameter tPE = 10000000; // Correct it
parameter tPE = 10000000; // Correct it
parameter tBE = 15000000; // Correct it
parameter tBE = 15000000; // Correct it
parameter tCAR = 200;
parameter tCAR = 200;
`endif
`endif
 
 
`ifdef device16M
`ifdef device16M
parameter tDIS = 25;
parameter tDIS = 25;
parameter tV = 30;
parameter tV = 30;
parameter tXFR = 350000;
parameter tXFR = 350000;
parameter tEP = 20000000;
parameter tEP = 20000000;
parameter tP = 15000000;
parameter tP = 15000000;
parameter tPE = 10000000;
parameter tPE = 10000000;
parameter tBE = 15000000;
parameter tBE = 15000000;
parameter tCAR = 200;
parameter tCAR = 200;
`endif
`endif
 
 
`ifdef device32M
`ifdef device32M
`ifdef ATFLASH_SPDUP
`ifdef ATFLASH_SPDUP
parameter tDIS = 25;
parameter tDIS = 25;
parameter tV = 30;
parameter tV = 30;
parameter tXFR = 35000;
parameter tXFR = 35000;
parameter tEP = 20000;
parameter tEP = 20000;
parameter tP = 15000;
parameter tP = 15000;
parameter tPE = 10000;
parameter tPE = 10000;
parameter tBE = 15000;
parameter tBE = 15000;
parameter tCAR = 200;
parameter tCAR = 200;
`else
`else
parameter tDIS = 25;
parameter tDIS = 25;
parameter tV = 30;
parameter tV = 30;
parameter tXFR = 350000;
parameter tXFR = 350000;
parameter tEP = 20000000;
parameter tEP = 20000000;
parameter tP = 15000000;
parameter tP = 15000000;
parameter tPE = 10000000;
parameter tPE = 10000000;
parameter tBE = 15000000;
parameter tBE = 15000000;
parameter tCAR = 200;
parameter tCAR = 200;
`endif
`endif
`endif
`endif
 
 
 
 
/**********************************************************************
/**********************************************************************
Memory PreLoading Parameters:
Memory PreLoading Parameters:
=============================
=============================
These parameters are related to Memory-Preloading. Since, we had to declare
These parameters are related to Memory-Preloading. Since, we had to declare
multiple memories, due to Verilog limitation; for PreLoading also, one may
multiple memories, due to Verilog limitation; for PreLoading also, one may
have to preload multiple memories.
have to preload multiple memories.
Any of the memories can be preloaded, in either Hex format, or, in Binary
Any of the memories can be preloaded, in either Hex format, or, in Binary
To load a memory (say memory0) in Hex format, define parameter: mem0_h
To load a memory (say memory0) in Hex format, define parameter: mem0_h
To load a memory (say memory0) in Binary format, define parameter: mem0_b
To load a memory (say memory0) in Binary format, define parameter: mem0_b
If none of the parameters are specified, the memory will be initialized to
If none of the parameters are specified, the memory will be initialized to
    Erase state.
    Erase state.
If both of the parameters are specified, the hex file will be used.
If both of the parameters are specified, the hex file will be used.
If any of the memory locations are initialized, the status of all the page
If any of the memory locations are initialized, the status of all the page
   will be Not-Erased.
   will be Not-Erased.
**********************************************************************/
**********************************************************************/
`ifdef SPI_PRELOAD_FNAME
`ifdef SPI_PRELOAD_FNAME
parameter mem0_h = `SPI_PRELOAD_FNAME;
parameter mem0_h = `SPI_PRELOAD_FNAME;
`else
`else
parameter mem0_h = "";
parameter mem0_h = "";
`endif
`endif
parameter mem1_h = "";
parameter mem1_h = "";
parameter mem2_h = "";
parameter mem2_h = "";
parameter mem3_h = "";
parameter mem3_h = "";
parameter mem4_h = "";
parameter mem4_h = "";
parameter mem5_h = "";
parameter mem5_h = "";
parameter mem6_h = "";
parameter mem6_h = "";
parameter mem7_h = "";
parameter mem7_h = "";
 
 
parameter mem0_b = "";
parameter mem0_b = "";
parameter mem1_b = "";
parameter mem1_b = "";
parameter mem2_b = "";
parameter mem2_b = "";
parameter mem3_b = "";
parameter mem3_b = "";
parameter mem4_b = "";
parameter mem4_b = "";
parameter mem5_b = "";
parameter mem5_b = "";
parameter mem6_b = "";
parameter mem6_b = "";
parameter mem7_b = "";
parameter mem7_b = "";
 
 
/********* Memory And Access Related Declarations *****************/
/********* Memory And Access Related Declarations *****************/
// Verilog seems to be having a restriction due to which, large
// Verilog seems to be having a restriction due to which, large
// memory-registers can not be used. Hence, declaring 8 smaller,
// memory-registers can not be used. Hence, declaring 8 smaller,
// equal size memories.
// equal size memories.
 
 
reg [7:0] memory0 [540671:0] ;
reg [7:0] memory0 [540671:0] ;
reg [7:0] memory1 [1081343:540672] ;
reg [7:0] memory1 [1081343:540672] ;
reg [7:0] memory2 [1622015:1081344] ;
reg [7:0] memory2 [1622015:1081344] ;
reg [7:0] memory3 [2162687:1622016] ;
reg [7:0] memory3 [2162687:1622016] ;
reg [7:0] memory4 [2703359:2162688] ;
reg [7:0] memory4 [2703359:2162688] ;
reg [7:0] memory5 [3244031:2703360] ;
reg [7:0] memory5 [3244031:2703360] ;
reg [7:0] memory6 [3784703:3244032] ;
reg [7:0] memory6 [3784703:3244032] ;
reg [7:0] memory7 [4325375:3784704] ;
reg [7:0] memory7 [4325375:3784704] ;
 
 
reg [7:0] buffer1 [PAGESIZE-1:0] ; //Buffer 1
reg [7:0] buffer1 [PAGESIZE-1:0] ; //Buffer 1
reg [7:0] buffer2 [PAGESIZE-1:0] ; //Buffer 2
reg [7:0] buffer2 [PAGESIZE-1:0] ; //Buffer 2
 
 
reg [PADDRESS-1:0] page ; // page address
reg [PADDRESS-1:0] page ; // page address
reg [BADDRESS-1:0] byte_new ; // byte_new address
reg [BADDRESS-1:0] byte_new ; // byte_new address
reg [7:0] status ; // status reg
reg [7:0] status ; // status reg
reg [PAGES-1:0] page_status;  // 0 means page-erased, otherwise not erased
reg [PAGES-1:0] page_status;  // 0 means page-erased, otherwise not erased
 
 
 
 
/********* Events to trigger some task based on opcode ***********/
/********* Events to trigger some task based on opcode ***********/
     event  MMPR ;  // Main Memory Page Read
     event  MMPR ;  // Main Memory Page Read
     event  B1R ;   // Buffer 1 Read
     event  B1R ;   // Buffer 1 Read
     event  B2R ;   // Buffer 2 Read
     event  B2R ;   // Buffer 2 Read
     event  MMPTB1T ;   // Main Memory Page To Buffer 1 Transfer
     event  MMPTB1T ;   // Main Memory Page To Buffer 1 Transfer
     event  MMPTB2T ;   // Main Memory Page To Buffer 2 Transfer
     event  MMPTB2T ;   // Main Memory Page To Buffer 2 Transfer
     event  MMPTB1C ;   // Main Memory Page To Buffer 1 Compare
     event  MMPTB1C ;   // Main Memory Page To Buffer 1 Compare
     event  MMPTB2C ;   // Main Memory Page To Buffer 2 Compare
     event  MMPTB2C ;   // Main Memory Page To Buffer 2 Compare
     event  B1W ;   // Buffer 1 Write
     event  B1W ;   // Buffer 1 Write
     event  B2W ;   // Buffer 2 Write
     event  B2W ;   // Buffer 2 Write
     event  B1TMMPPWBIE ;   // Buffer 1 To Main Memory Page Prog 
     event  B1TMMPPWBIE ;   // Buffer 1 To Main Memory Page Prog 
                                     //With Built-In Erase 
                                     //With Built-In Erase 
     event  B2TMMPPWBIE ;   // Buffer 2 To Main Memory Page Prog 
     event  B2TMMPPWBIE ;   // Buffer 2 To Main Memory Page Prog 
                                     //With Built-In Erase 
                                     //With Built-In Erase 
     event  B1TMMPPWOBIE ;   // Buffer 1 To Main Memory Page Prog 
     event  B1TMMPPWOBIE ;   // Buffer 1 To Main Memory Page Prog 
                                     //WithoOut Built-In Erase 
                                     //WithoOut Built-In Erase 
     event  B2TMMPPWOBIE ;   // Buffer 2 To Main Memory Page Prog 
     event  B2TMMPPWOBIE ;   // Buffer 2 To Main Memory Page Prog 
                                     //WithoOut Built-In Erase 
                                     //WithoOut Built-In Erase 
     event  PE ;   // Page Erase
     event  PE ;   // Page Erase
     event  BE ;   // Block Erase
     event  BE ;   // Block Erase
     event  MMPPB1 ;   // Main Memory Page Prog. Through Buffer 1
     event  MMPPB1 ;   // Main Memory Page Prog. Through Buffer 1
     event  MMPPB2 ;   // Main Memory Page Prog. Through Buffer 2
     event  MMPPB2 ;   // Main Memory Page Prog. Through Buffer 2
     event  APRB1 ;   // Auto Page Rewrite Through Buffer 1
     event  APRB1 ;   // Auto Page Rewrite Through Buffer 1
     event  APRB2 ;   // Auto Page Rewrite Through Buffer 2
     event  APRB2 ;   // Auto Page Rewrite Through Buffer 2
     event  SR ;   // Status Register Read
     event  SR ;   // Status Register Read
     event  RWOPR ; // This is basically same as MMPR, except that rollover
     event  RWOPR ; // This is basically same as MMPR, except that rollover
                    // at the end of a page does not occur;
                    // at the end of a page does not occur;
 
 
/********* Registers to track the current operation of the device ********/
/********* Registers to track the current operation of the device ********/
reg status_read;
reg status_read;
reg updating_buffer1;
reg updating_buffer1;
reg updating_buffer2;
reg updating_buffer2;
reg updating_memory;
reg updating_memory;
reg comparing;
reg comparing;
reg erasing_page;
reg erasing_page;
reg erasing_block;
reg erasing_block;
reg skip; // reg to denote whether or no an extra clock needs to be skipped.
reg skip; // reg to denote whether or no an extra clock needs to be skipped.
          // This skipping is needed only for Inactive Clock Low. 
          // This skipping is needed only for Inactive Clock Low. 
 
 
 
 
/******** Other variables/registers/events ******************/
/******** Other variables/registers/events ******************/
reg [7:0] read_data; // temp. register in which data is read-in
reg [7:0] read_data; // temp. register in which data is read-in
reg [7:0] temp_reg1; // temp. register to store temporary data
reg [7:0] temp_reg1; // temp. register to store temporary data
reg [7:0] temp_reg2; // temp. register to store temporary data
reg [7:0] temp_reg2; // temp. register to store temporary data
reg [PADDRESS-1:0] temp_page; // temp register to store page-address
reg [PADDRESS-1:0] temp_page; // temp register to store page-address
reg SO_reg , SO_on ;
reg SO_reg , SO_on ;
reg RDYBSY_reg;
reg RDYBSY_reg;
integer j;
integer j;
integer page_boundary_low, page_boundary_high, current_address;
integer page_boundary_low, page_boundary_high, current_address;
integer mem_no; // this will keep track of the actual memory to be used.
integer mem_no; // this will keep track of the actual memory to be used.
reg mem_initialized;
reg mem_initialized;
 
 
 
 
/********* Drive SO ***********************/
/********* Drive SO ***********************/
bufif1 (SO, SO_reg, SO_on); //SO will be driven only if SO_on is High
bufif1 (SO, SO_reg, SO_on); //SO will be driven only if SO_on is High
bufif1 (RDY_BUSYB, 1'b0, RDYBSY_reg); //RDYBUSYB will be driven only if RDYBSY_reg is High
bufif1 (RDY_BUSYB, 1'b0, RDYBSY_reg); //RDYBUSYB will be driven only if RDYBSY_reg is High
 
 
 
 
/********* Initialize **********************/
/********* Initialize **********************/
initial
initial
begin
begin
    // start with erased state
    // start with erased state
    // Memory Initialization
    // Memory Initialization
  mem_initialized = 1'b0;
  mem_initialized = 1'b0;
 
 
  for (j=0; j<540672; j=j+1)   // Pre-initiazliation to Erased
  for (j=0; j<540672; j=j+1)   // Pre-initiazliation to Erased
  begin                        // state is useful if a user wants to
  begin                        // state is useful if a user wants to
    memory0[j] = 8'hff;        // initialize just a few locations.
    memory0[j] = 8'hff;        // initialize just a few locations.
    memory1[j+540672] = 8'hff;
    memory1[j+540672] = 8'hff;
    memory2[j+1081344] = 8'hff;
    memory2[j+1081344] = 8'hff;
    memory3[j+1622016] = 8'hff;
    memory3[j+1622016] = 8'hff;
    memory4[j+2162688] = 8'hff;
    memory4[j+2162688] = 8'hff;
    memory5[j+2703360] = 8'hff;
    memory5[j+2703360] = 8'hff;
    memory6[j+3244032] = 8'hff;
    memory6[j+3244032] = 8'hff;
    memory7[j+3784704] = 8'hff;
    memory7[j+3784704] = 8'hff;
  end
  end
 
 
   // Now preload, if needed
   // Now preload, if needed
  if (mem0_h != "")
  if (mem0_h != "")
  begin
  begin
     $readmemh (mem0_h, memory0);
     $readmemh (mem0_h, memory0);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
  else if (mem0_b != "")
  else if (mem0_b != "")
  begin
  begin
     $readmemb (mem0_b, memory0);
     $readmemb (mem0_b, memory0);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
 
 
  if (mem1_h != "")
  if (mem1_h != "")
  begin
  begin
     $readmemh (mem1_h, memory1);
     $readmemh (mem1_h, memory1);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
  else if (mem1_b != "")
  else if (mem1_b != "")
  begin
  begin
     $readmemb (mem1_b, memory1);
     $readmemb (mem1_b, memory1);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
 
 
  if (mem2_h != "")
  if (mem2_h != "")
  begin
  begin
     $readmemh (mem2_h, memory2);
     $readmemh (mem2_h, memory2);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
  else if (mem2_b != "")
  else if (mem2_b != "")
  begin
  begin
     $readmemb (mem2_b, memory2);
     $readmemb (mem2_b, memory2);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
 
 
  if (mem3_h != "")
  if (mem3_h != "")
  begin
  begin
     $readmemh (mem3_h, memory3);
     $readmemh (mem3_h, memory3);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
  else if (mem3_b != "")
  else if (mem3_b != "")
  begin
  begin
     $readmemb (mem3_b, memory3);
     $readmemb (mem3_b, memory3);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
 
 
  if (mem4_h != "")
  if (mem4_h != "")
  begin
  begin
     $readmemh (mem4_h, memory4);
     $readmemh (mem4_h, memory4);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
  else if (mem4_b != "")
  else if (mem4_b != "")
  begin
  begin
     $readmemb (mem4_b, memory4);
     $readmemb (mem4_b, memory4);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
 
 
  if (mem5_h != "")
  if (mem5_h != "")
  begin
  begin
     $readmemh (mem5_h, memory5);
     $readmemh (mem5_h, memory5);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
  else if (mem5_b != "")
  else if (mem5_b != "")
  begin
  begin
     $readmemb (mem5_b, memory5);
     $readmemb (mem5_b, memory5);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
 
 
  if (mem6_h != "")
  if (mem6_h != "")
  begin
  begin
     $readmemh (mem6_h, memory6);
     $readmemh (mem6_h, memory6);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
  else if (mem6_b != "")
  else if (mem6_b != "")
  begin
  begin
     $readmemb (mem6_b, memory6);
     $readmemb (mem6_b, memory6);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
 
 
  if (mem7_h != "")
  if (mem7_h != "")
  begin
  begin
     $readmemh (mem7_h, memory7);
     $readmemh (mem7_h, memory7);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
  else if (mem7_b != "")
  else if (mem7_b != "")
  begin
  begin
     $readmemb (mem7_b, memory7);
     $readmemb (mem7_b, memory7);
     mem_initialized = 1'b1;
     mem_initialized = 1'b1;
  end
  end
 
 
  if (mem_initialized == 1'b1)
  if (mem_initialized == 1'b1)
  for (j=0; j<PAGES; j=j+1)
  for (j=0; j<PAGES; j=j+1)
    page_status[j] = 1'b1; // memory was initialized, so, Pages are Not Erased.
    page_status[j] = 1'b1; // memory was initialized, so, Pages are Not Erased.
  else
  else
  for (j=0; j<PAGES; j=j+1)
  for (j=0; j<PAGES; j=j+1)
    page_status[j] = 1'b0;
    page_status[j] = 1'b0;
 
 
  // Now initialize all registers
  // Now initialize all registers
  status[7] = 1'b1; // device is ready to start with
  status[7] = 1'b1; // device is ready to start with
  status[6] = 1'bx; // compare bit is unknown
  status[6] = 1'bx; // compare bit is unknown
  status[5] = STATUS5;
  status[5] = STATUS5;
  status[4] = STATUS4;
  status[4] = STATUS4;
  status[3] = STATUS3;
  status[3] = STATUS3;
  status[2:0] = 3'bx; // these reserved bits are also unknown
  status[2:0] = 3'bx; // these reserved bits are also unknown
 
 
  // There is no activity at this time
  // There is no activity at this time
  status_read = 1'b0;
  status_read = 1'b0;
  updating_buffer1 = 1'b0;
  updating_buffer1 = 1'b0;
  updating_buffer2 = 1'b0;
  updating_buffer2 = 1'b0;
  updating_memory = 1'b0;
  updating_memory = 1'b0;
  comparing = 1'b0;
  comparing = 1'b0;
  erasing_page = 1'b0;
  erasing_page = 1'b0;
  erasing_block = 1'b0;
  erasing_block = 1'b0;
 
 
  // All o/ps are High-impedance
  // All o/ps are High-impedance
  SO_on = 1'b0;
  SO_on = 1'b0;
  RDYBSY_reg = 1'b0;
  RDYBSY_reg = 1'b0;
 
 
end
end
 
 
 
 
always @(negedge CSB)  // the device will now become active
always @(negedge CSB)  // the device will now become active
begin : get_opcode
begin : get_opcode
   if (SCK == 1'b0)
   if (SCK == 1'b0)
   begin
   begin
      skip = 1'b1;
      skip = 1'b1;
 
 
   end
   end
   else
   else
   begin
   begin
      skip = 1'b0;
      skip = 1'b0;
      // If the opcode is related to SPI Mode 0/3, no skipping is needed. So, skip
      // If the opcode is related to SPI Mode 0/3, no skipping is needed. So, skip
      // will be reset to "0".
      // will be reset to "0".
      // If opcode is related to Inactive Clock Low/high, skipping might or might
      // If opcode is related to Inactive Clock Low/high, skipping might or might
      // not be needed, depending on the value of SCK at negedge of CSB. So, in
      // not be needed, depending on the value of SCK at negedge of CSB. So, in
      // such situations, skip will retain its value.
      // such situations, skip will retain its value.
    end
    end
 
 
   get_data;  // get opcode here
   get_data;  // get opcode here
 
 
   case (status[5:3])
   case (status[5:3])
     3'b001:  // 1M Memory
     3'b001:  // 1M Memory
         case (read_data)
         case (read_data)
           // Illegal Opcode for 1M memory. It has only one buffer.
           // Illegal Opcode for 1M memory. It has only one buffer.
           8'h56, 8'hd6, 8'h55, 8'h61, 8'h87, 8'h86, 8'h89, 8'h85, 8'h59:
           8'h56, 8'hd6, 8'h55, 8'h61, 8'h87, 8'h86, 8'h89, 8'h85, 8'h59:
              begin
              begin
                $display("Unrecognized opcode %h", read_data);
                $display("Unrecognized opcode %h", read_data);
                disable get_opcode;
                disable get_opcode;
              end
              end
         endcase
         endcase
   endcase
   endcase
 
 
   case (read_data)   // based on opcode, trigger an action
   case (read_data)   // based on opcode, trigger an action
     8'h52 : -> MMPR ;  // Main Memory Page Read
     8'h52 : -> MMPR ;  // Main Memory Page Read
     8'hd2 : begin
     8'hd2 : begin
               skip = 1'b0;
               skip = 1'b0;
               -> MMPR ;  // Main Memory Page Read
               -> MMPR ;  // Main Memory Page Read
             end
             end
     8'h54 : -> B1R ;   // Buffer 1 Read
     8'h54 : -> B1R ;   // Buffer 1 Read
     8'hd4 : begin
     8'hd4 : begin
               skip = 1'b0;
               skip = 1'b0;
               -> B1R ;   // Buffer 1 Read
               -> B1R ;   // Buffer 1 Read
             end
             end
     8'h56 : -> B2R ;   // Buffer 2 Read
     8'h56 : -> B2R ;   // Buffer 2 Read
     8'hd6 : begin
     8'hd6 : begin
               skip = 1'b0;
               skip = 1'b0;
               -> B2R ;   // Buffer 2 Read
               -> B2R ;   // Buffer 2 Read
             end
             end
     8'h53 : -> MMPTB1T ;   // Main Memory Page To Buffer 1 Transfer
     8'h53 : -> MMPTB1T ;   // Main Memory Page To Buffer 1 Transfer
     8'h55 : -> MMPTB2T ;   // Main Memory Page To Buffer 2 Transfer
     8'h55 : -> MMPTB2T ;   // Main Memory Page To Buffer 2 Transfer
     8'h60 : -> MMPTB1C ;   // Main Memory Page To Buffer 1 Compare
     8'h60 : -> MMPTB1C ;   // Main Memory Page To Buffer 1 Compare
     8'h61 : -> MMPTB2C ;   // Main Memory Page To Buffer 2 Compare
     8'h61 : -> MMPTB2C ;   // Main Memory Page To Buffer 2 Compare
     8'h84 : -> B1W ;   // Buffer 1 Write
     8'h84 : -> B1W ;   // Buffer 1 Write
     8'h87 : -> B2W ;   // Buffer 2 Write
     8'h87 : -> B2W ;   // Buffer 2 Write
     8'h83 : -> B1TMMPPWBIE ;   // Buffer 1 To Main Memory Page Prog 
     8'h83 : -> B1TMMPPWBIE ;   // Buffer 1 To Main Memory Page Prog 
                                               //With Built-In Erase 
                                               //With Built-In Erase 
     8'h86 : -> B2TMMPPWBIE ;   // Buffer 2 To Main Memory Page Prog 
     8'h86 : -> B2TMMPPWBIE ;   // Buffer 2 To Main Memory Page Prog 
                                               //With Built-In Erase 
                                               //With Built-In Erase 
     8'h88 : -> B1TMMPPWOBIE ;   // Buffer 1 To Main Memory Page Prog 
     8'h88 : -> B1TMMPPWOBIE ;   // Buffer 1 To Main Memory Page Prog 
                                               //WithoOut Built-In Erase 
                                               //WithoOut Built-In Erase 
     8'h89 : -> B2TMMPPWOBIE ;   // Buffer 2 To Main Memory Page Prog 
     8'h89 : -> B2TMMPPWOBIE ;   // Buffer 2 To Main Memory Page Prog 
                                               //WithoOut Built-In Erase 
                                               //WithoOut Built-In Erase 
     8'h81 : -> PE ;   // Page Erase
     8'h81 : -> PE ;   // Page Erase
     8'h50 : -> BE ;   // Block Erase
     8'h50 : -> BE ;   // Block Erase
     8'h82 : -> MMPPB1 ;   // Main Memory Page Prog. Through Buffer 1
     8'h82 : -> MMPPB1 ;   // Main Memory Page Prog. Through Buffer 1
     8'h85 : -> MMPPB2 ;   // Main Memory Page Prog. Through Buffer 2
     8'h85 : -> MMPPB2 ;   // Main Memory Page Prog. Through Buffer 2
     8'h58 : -> APRB1 ;   // Auto Page Rewrite Through Buffer 1
     8'h58 : -> APRB1 ;   // Auto Page Rewrite Through Buffer 1
     8'h59 : -> APRB2 ;   // Auto Page Rewrite Through Buffer 2
     8'h59 : -> APRB2 ;   // Auto Page Rewrite Through Buffer 2
     8'h57 : -> SR ;   // Status Register Read
     8'h57 : -> SR ;   // Status Register Read
     8'hd7 : begin
     8'hd7 : begin
               skip = 1'b0;
               skip = 1'b0;
               -> SR ;   // Status Register Read
               -> SR ;   // Status Register Read
             end
             end
     8'h68 : -> RWOPR ;
     8'h68 : -> RWOPR ;
     8'hE8 : begin
     8'hE8 : begin
               skip = 1'b0;
               skip = 1'b0;
               -> RWOPR ;
               -> RWOPR ;
             end
             end
     default : $display ("Unrecognized opcode %h", read_data);
     default : $display ("Unrecognized opcode %h", read_data);
   endcase
   endcase
end
end
 
 
 
 
/******* Main Memory Page Read ********************/
/******* Main Memory Page Read ********************/
 
 
always @(MMPR)
always @(MMPR)
begin : MMPR_
begin : MMPR_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Main Memory Page Read is not allowed");
     $display ("Device is busy. Main Memory Page Read is not allowed");
     disable MMPR_ ;
     disable MMPR_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress and byte_new-address, according to 
        // within PageAddress and byte_new-address, according to 
        // the parameters.
        // the parameters.
   compute_page_address;
   compute_page_address;
   compute_byte_new_address;
   compute_byte_new_address;
      // next 8 bits always contain byte_new-address[7:0], and, so is
      // next 8 bits always contain byte_new-address[7:0], and, so is
      // not dependent on parameters
      // not dependent on parameters
   get_data;
   get_data;
   byte_new[7:0] = read_data[7:0];
   byte_new[7:0] = read_data[7:0];
 
 
   for (j=0; j<4; j=j+1)
   for (j=0; j<4; j=j+1)
      get_data ;  // these 32 bits are dont-care, and so have been discarded.
      get_data ;  // these 32 bits are dont-care, and so have been discarded.
 
 
   compute_address;
   compute_address;
   if (skip == 1'b1)
   if (skip == 1'b1)
     @(posedge SCK); // skip one SCK
     @(posedge SCK); // skip one SCK
   read_out (mem_no, current_address, page_boundary_low, page_boundary_high);
   read_out (mem_no, current_address, page_boundary_low, page_boundary_high);
end
end
 
 
 
 
/******* Buffer 1 Read ********************/
/******* Buffer 1 Read ********************/
 
 
always @(B1R)
always @(B1R)
begin : B1R_
begin : B1R_
   get_data; // first 8 bits are dont care
   get_data; // first 8 bits are dont care
   get_data;
   get_data;
        // For buffers, PageAddress can be assumed as "0".
        // For buffers, PageAddress can be assumed as "0".
        // This will allow us to share code with MMPR;
        // This will allow us to share code with MMPR;
   page [PADDRESS-1:0] = 'h0;
   page [PADDRESS-1:0] = 'h0;
 
 
   compute_byte_new_address;
   compute_byte_new_address;
      // next 8 bits always contain byte_new-address[7:0], and, so is
      // next 8 bits always contain byte_new-address[7:0], and, so is
      // not dependent on parameters
      // not dependent on parameters
   get_data;
   get_data;
   byte_new[7:0] = read_data[7:0];
   byte_new[7:0] = read_data[7:0];
 
 
   compute_address;
   compute_address;
   get_data; // next 8 bits are dont care
   get_data; // next 8 bits are dont care
   if (skip == 1'b1)
   if (skip == 1'b1)
     @(posedge SCK); // skip one SCK
     @(posedge SCK); // skip one SCK
   read_out (1, current_address, page_boundary_low, page_boundary_high);
   read_out (1, current_address, page_boundary_low, page_boundary_high);
end
end
 
 
 
 
 
 
/******* Buffer 2 Read ********************/
/******* Buffer 2 Read ********************/
 
 
always @(B2R)
always @(B2R)
begin : B2R_
begin : B2R_
   get_data; // first 8 bits are dont care
   get_data; // first 8 bits are dont care
   get_data;
   get_data;
        // For buffers, PageAddress can be assumed as "0".
        // For buffers, PageAddress can be assumed as "0".
        // This will allow us to share code with MMPR;
        // This will allow us to share code with MMPR;
   page [PADDRESS-1:0] = 'h0;
   page [PADDRESS-1:0] = 'h0;
 
 
   compute_byte_new_address;
   compute_byte_new_address;
 
 
      // next 8 bits always contain byte_new-address[7:0], and, so is
      // next 8 bits always contain byte_new-address[7:0], and, so is
      // not dependent on parameters
      // not dependent on parameters
   get_data;
   get_data;
   byte_new[7:0] = read_data[7:0];
   byte_new[7:0] = read_data[7:0];
 
 
   compute_address;
   compute_address;
   get_data; // next 8 bits are don't care
   get_data; // next 8 bits are don't care
   if (skip == 1'b1)
   if (skip == 1'b1)
     @(posedge SCK); // skip one SCK
     @(posedge SCK); // skip one SCK
   read_out (2, current_address, page_boundary_low, page_boundary_high);
   read_out (2, current_address, page_boundary_low, page_boundary_high);
end
end
 
 
 
 
/******* Main Memory Page To Buffer 1 Transfer *****************/
/******* Main Memory Page To Buffer 1 Transfer *****************/
 
 
always @(MMPTB1T)
always @(MMPTB1T)
begin : MMPTB1T_
begin : MMPTB1T_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Main Memory To Buffer Transfer is not allowed");
     $display ("Device is busy. Main Memory To Buffer Transfer is not allowed");
     disable MMPTB1T_ ;
     disable MMPTB1T_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   transfer_to_buffer (1, page_boundary_low);
   transfer_to_buffer (1, page_boundary_low);
   updating_buffer1 = 1'b1;
   updating_buffer1 = 1'b1;
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   updating_buffer1 = 1'b0;
   updating_buffer1 = 1'b0;
end
end
 
 
 
 
/******* Main Memory Page To Buffer 2 Transfer *****************/
/******* Main Memory Page To Buffer 2 Transfer *****************/
 
 
always @(MMPTB2T)
always @(MMPTB2T)
begin : MMPTB2T_
begin : MMPTB2T_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Main Memory To Buffer Transfer is not allowed");
     $display ("Device is busy. Main Memory To Buffer Transfer is not allowed");
     disable MMPTB2T_ ;
     disable MMPTB2T_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   transfer_to_buffer (2, page_boundary_low);
   transfer_to_buffer (2, page_boundary_low);
   updating_buffer2 = 1'b1;
   updating_buffer2 = 1'b1;
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   updating_buffer2 = 1'b0;
   updating_buffer2 = 1'b0;
end
end
 
 
 
 
/******* Main Memory Page To Buffer 1 Compare *****************/
/******* Main Memory Page To Buffer 1 Compare *****************/
 
 
always @(MMPTB1C)
always @(MMPTB1C)
begin : MMPTB1C_
begin : MMPTB1C_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Main Memory To Buffer Compare is not allowed");
     $display ("Device is busy. Main Memory To Buffer Compare is not allowed");
     disable MMPTB1C_ ;
     disable MMPTB1C_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   compare_with_buffer (1, page_boundary_low);
   compare_with_buffer (1, page_boundary_low);
   comparing = 1'b1;
   comparing = 1'b1;
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   comparing = 1'b0;
   comparing = 1'b0;
end
end
 
 
 
 
 
 
/******* Main Memory Page To Buffer 2 Compare *****************/
/******* Main Memory Page To Buffer 2 Compare *****************/
 
 
always @(MMPTB2C)
always @(MMPTB2C)
begin : MMPTB2C_
begin : MMPTB2C_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Main Memory To Buffer Compare is not allowed");
     $display ("Device is busy. Main Memory To Buffer Compare is not allowed");
     disable MMPTB2C_ ;
     disable MMPTB2C_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   compare_with_buffer (2, page_boundary_low);
   compare_with_buffer (2, page_boundary_low);
   comparing = 1'b1;
   comparing = 1'b1;
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
   #tXFR RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   comparing = 1'b0;
   comparing = 1'b0;
end
end
 
 
 
 
/*******    Buffer 1 Write *****************/
/*******    Buffer 1 Write *****************/
 
 
always @(B1W)
always @(B1W)
begin : B1W_
begin : B1W_
   get_data; // dont care bits
   get_data; // dont care bits
   get_data;
   get_data;
            // got some address bits, depending on device parameters
            // got some address bits, depending on device parameters
   compute_byte_new_address;
   compute_byte_new_address;
   get_data;
   get_data;
   byte_new[7:0] = read_data [7:0];
   byte_new[7:0] = read_data [7:0];
 
 
   page[PADDRESS-1:0] = 'h0; // buffer is equivalent to just one page
   page[PADDRESS-1:0] = 'h0; // buffer is equivalent to just one page
 
 
   compute_address;
   compute_address;
 
 
   write_data (1);
   write_data (1);
 
 
end
end
 
 
 
 
/*******    Buffer 2 Write *****************/
/*******    Buffer 2 Write *****************/
 
 
always @(B2W)
always @(B2W)
begin : B2W_
begin : B2W_
   get_data; // dont care bits
   get_data; // dont care bits
   get_data;
   get_data;
            // got some address bits, depending on device parameters
            // got some address bits, depending on device parameters
   compute_byte_new_address;
   compute_byte_new_address;
   get_data;
   get_data;
   byte_new[7:0] = read_data [7:0];
   byte_new[7:0] = read_data [7:0];
 
 
   page[PADDRESS-1:0] = 'h0; // buffer is equivalent to just one page
   page[PADDRESS-1:0] = 'h0; // buffer is equivalent to just one page
 
 
   compute_address;
   compute_address;
 
 
   write_data (2);
   write_data (2);
 
 
end
end
 
 
 
 
/******* Buffer 1 To Main Memory Page Prog With Built In Erase *******/
/******* Buffer 1 To Main Memory Page Prog With Built In Erase *******/
 
 
always @(B1TMMPPWBIE)
always @(B1TMMPPWBIE)
begin : B1TMMPPWBIE_
begin : B1TMMPPWBIE_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
     disable B1TMMPPWBIE_ ;
     disable B1TMMPPWBIE_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
     disable B1TMMPPWBIE_ ;
     disable B1TMMPPWBIE_ ;
   end
   end
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   write_to_memory (1, page_boundary_low);
   write_to_memory (1, page_boundary_low);
   updating_memory = 1'b1;
   updating_memory = 1'b1;
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   updating_memory = 1'b0;
   updating_memory = 1'b0;
end
end
 
 
 
 
/******* Buffer 2 To Main Memory Page Prog With Built In Erase *******/
/******* Buffer 2 To Main Memory Page Prog With Built In Erase *******/
 
 
always @(B2TMMPPWBIE)
always @(B2TMMPPWBIE)
begin : B2TMMPPWBIE_
begin : B2TMMPPWBIE_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
     disable B2TMMPPWBIE_ ;
     disable B2TMMPPWBIE_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
     disable B2TMMPPWBIE_ ;
     disable B2TMMPPWBIE_ ;
   end
   end
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   write_to_memory (2, page_boundary_low);
   write_to_memory (2, page_boundary_low);
   updating_memory = 1'b1;
   updating_memory = 1'b1;
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   updating_memory = 1'b0;
   updating_memory = 1'b0;
end
end
 
 
 
 
/******* Buffer 1 To Main Memory Page Prog WithOut Built In Erase *******/
/******* Buffer 1 To Main Memory Page Prog WithOut Built In Erase *******/
 
 
always @(B1TMMPPWOBIE)
always @(B1TMMPPWOBIE)
begin : B1TMMPPWOBIE_
begin : B1TMMPPWOBIE_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
     disable B1TMMPPWOBIE_ ;
     disable B1TMMPPWOBIE_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
     disable B1TMMPPWOBIE_ ;
     disable B1TMMPPWOBIE_ ;
   end
   end
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   if (page_status[page] == 1'b0) // page is already erased
   if (page_status[page] == 1'b0) // page is already erased
   begin
   begin
      RDYBSY_reg = 1'b1; // device is busy
      RDYBSY_reg = 1'b1; // device is busy
      status[7] = 1'b0;
      status[7] = 1'b0;
      write_to_memory (1, page_boundary_low);
      write_to_memory (1, page_boundary_low);
      updating_memory = 1'b1;
      updating_memory = 1'b1;
      #tP RDYBSY_reg = 1'b0; // device is now ready
      #tP RDYBSY_reg = 1'b0; // device is now ready
      status[7] = 1'b1;
      status[7] = 1'b1;
      updating_memory = 1'b0;
      updating_memory = 1'b0;
   end
   end
   else
   else
      $display ("Trying to write into Page %d which is not erased", page);
      $display ("Trying to write into Page %d which is not erased", page);
end
end
 
 
 
 
/******* Buffer 2 To Main Memory Page Prog WithOut Built In Erase *******/
/******* Buffer 2 To Main Memory Page Prog WithOut Built In Erase *******/
 
 
always @(B2TMMPPWOBIE)
always @(B2TMMPPWOBIE)
begin : B2TMMPPWOBIE_
begin : B2TMMPPWOBIE_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
     $display ("Device is busy. Buffer To Main Memory Page Prog. is not allowed");
     disable B2TMMPPWOBIE_ ;
     disable B2TMMPPWOBIE_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't write: Page No. %d is Protected, becase WPB is Low", page);
     disable B2TMMPPWOBIE_ ;
     disable B2TMMPPWOBIE_ ;
   end
   end
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   if (page_status[page] == 1'b0) // page is already erased
   if (page_status[page] == 1'b0) // page is already erased
   begin
   begin
      RDYBSY_reg = 1'b1; // device is busy
      RDYBSY_reg = 1'b1; // device is busy
      status[7] = 1'b0;
      status[7] = 1'b0;
      updating_memory = 1'b1;
      updating_memory = 1'b1;
      write_to_memory (2, page_boundary_low);
      write_to_memory (2, page_boundary_low);
      #tP RDYBSY_reg = 1'b0; // device is now ready
      #tP RDYBSY_reg = 1'b0; // device is now ready
      status[7] = 1'b1;
      status[7] = 1'b1;
      updating_memory = 1'b0;
      updating_memory = 1'b0;
   end
   end
   else
   else
      $display ("Trying to write into Page %d which is not erased", page);
      $display ("Trying to write into Page %d which is not erased", page);
end
end
 
 
 
 
/******* Page Erase *******/
/******* Page Erase *******/
 
 
always @(PE)
always @(PE)
begin : PE_
begin : PE_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Page Erase is not allowed");
     $display ("Device is busy. Page Erase is not allowed");
     disable PE_ ;
     disable PE_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't Erase: Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't Erase: Page No. %d is Protected, becase WPB is Low", page);
     disable PE_ ;
     disable PE_ ;
   end
   end
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   erase_page ( page_boundary_low);
   erase_page ( page_boundary_low);
   erasing_page = 1'b1;
   erasing_page = 1'b1;
   #tPE RDYBSY_reg = 1'b0; // device is now ready
   #tPE RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   erasing_page = 1'b0;
   erasing_page = 1'b0;
end
end
 
 
 
 
/******* Block Erase *******/
/******* Block Erase *******/
 
 
always @(BE)
always @(BE)
begin : BE_
begin : BE_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Block Erase is not allowed");
     $display ("Device is busy. Block Erase is not allowed");
     disable BE_ ;
     disable BE_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
   page [2:0] = 3'h0; // lowest page of the block
   page [2:0] = 3'h0; // lowest page of the block
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't Erase: Block starting at Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't Erase: Block starting at Page No. %d is Protected, becase WPB is Low", page);
     disable BE_ ;
     disable BE_ ;
   end
   end
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
 
 
   for (j=page_boundary_low; j<(page_boundary_low+8*PAGESIZE); j=j+PAGESIZE)
   for (j=page_boundary_low; j<(page_boundary_low+8*PAGESIZE); j=j+PAGESIZE)
      erase_page ( j ); // erase 8 pages, i.e. a block
      erase_page ( j ); // erase 8 pages, i.e. a block
 
 
   for (j=0; j<8; j=j+1) // erase_page will only change the status of one-page 
   for (j=0; j<8; j=j+1) // erase_page will only change the status of one-page 
     page_status[page+j] = 1'b0; // hence, changing the remaining ones explicitly
     page_status[page+j] = 1'b0; // hence, changing the remaining ones explicitly
 
 
   erasing_block = 1'b1;
   erasing_block = 1'b1;
   #tBE RDYBSY_reg = 1'b0; // device is now ready
   #tBE RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   erasing_block = 1'b0;
   erasing_block = 1'b0;
end
end
 
 
/******* Main Memory Page Prog Through Buffer 1 *******/
/******* Main Memory Page Prog Through Buffer 1 *******/
 
 
always @(MMPPB1)
always @(MMPPB1)
begin : MMPPB1_
begin : MMPPB1_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Main Memory Page Prog. is not allowed");
     $display ("Device is busy. Main Memory Page Prog. is not allowed");
     disable MMPPB1_ ;
     disable MMPPB1_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress/ByteAddress according to the parameters
        // within PageAddress/ByteAddress according to the parameters
   compute_page_address;
   compute_page_address;
   compute_byte_new_address;
   compute_byte_new_address;
   temp_reg2[7:0] = read_data [7:0];
   temp_reg2[7:0] = read_data [7:0];
   get_data;
   get_data;
   byte_new[7:0] = read_data[7:0];
   byte_new[7:0] = read_data[7:0];
   temp_page = page; // page value has been stored for main memory page program
   temp_page = page; // page value has been stored for main memory page program
 
 
 
 
   page[PADDRESS-1:0] = 'h0; // Buffer is 0 pages
   page[PADDRESS-1:0] = 'h0; // Buffer is 0 pages
 
 
   compute_address; // this computes where to write in buffer
   compute_address; // this computes where to write in buffer
 
 
   write_data (1); // this will write to buffer
   write_data (1); // this will write to buffer
                   // it will proceed to next step, when, posedge of CSB.
                   // it will proceed to next step, when, posedge of CSB.
                   // This is complicated, and, hence, explained here:
                   // This is complicated, and, hence, explained here:
                   // At posedge of CSB, the write_data will get disabled.
                   // At posedge of CSB, the write_data will get disabled.
                   // At this time, writing to buffer needs to stop, and,
                   // At this time, writing to buffer needs to stop, and,
                   // writing into memory should start.
                   // writing into memory should start.
 
 
   page[PADDRESS-1:0] = temp_page[PADDRESS-1:0]; // page address in Main Memory to which
   page[PADDRESS-1:0] = temp_page[PADDRESS-1:0]; // page address in Main Memory to which
                                                 // data needs to be written
                                                 // data needs to be written
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't Write: Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't Write: Page No. %d is Protected, becase WPB is Low", page);
     disable MMPPB1_ ;
     disable MMPPB1_ ;
   end
   end
 
 
   compute_address; // even if byte_new-address is junk, we only need Page_Low_Boundary
   compute_address; // even if byte_new-address is junk, we only need Page_Low_Boundary
 
 
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   write_to_memory (1, page_boundary_low);
   write_to_memory (1, page_boundary_low);
   updating_memory = 1'b1;
   updating_memory = 1'b1;
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   updating_memory = 1'b0;
   updating_memory = 1'b0;
end
end
 
 
 
 
/******* Main Memory Page Prog Through Buffer 2 *******/
/******* Main Memory Page Prog Through Buffer 2 *******/
 
 
always @(MMPPB2)
always @(MMPPB2)
begin : MMPPB2_
begin : MMPPB2_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Main Memory Page Prog. is not allowed");
     $display ("Device is busy. Main Memory Page Prog. is not allowed");
     disable MMPPB2_ ;
     disable MMPPB2_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress/ByteAddress according to the parameters
        // within PageAddress/ByteAddress according to the parameters
   compute_page_address;
   compute_page_address;
   compute_byte_new_address;
   compute_byte_new_address;
   temp_reg2[7:0] = read_data [7:0];
   temp_reg2[7:0] = read_data [7:0];
   get_data;
   get_data;
   // Third byte_new is always for byte_new address[7:0]
   // Third byte_new is always for byte_new address[7:0]
   byte_new[7:0] = read_data[7:0];
   byte_new[7:0] = read_data[7:0];
 
 
   temp_page = page; // page value has been stored for main memory page program
   temp_page = page; // page value has been stored for main memory page program
 
 
   page[PADDRESS-1:0] = 'h0; // Buffer is 0 pages
   page[PADDRESS-1:0] = 'h0; // Buffer is 0 pages
 
 
   compute_address; // this computes where to write in buffer
   compute_address; // this computes where to write in buffer
 
 
   write_data (2); // this will write to buffer
   write_data (2); // this will write to buffer
                   // it will proceed to next step, when, posedge of CSB.
                   // it will proceed to next step, when, posedge of CSB.
                   // This is complicated, and, hence, explained here:
                   // This is complicated, and, hence, explained here:
                   // At posedge of CSB, the write_data will get disabled.
                   // At posedge of CSB, the write_data will get disabled.
                   // At this time, writing to buffer needs to stop, and,
                   // At this time, writing to buffer needs to stop, and,
                   // writing into memory should start.
                   // writing into memory should start.
 
 
   page[PADDRESS-1:0] = temp_page[PADDRESS-1:0]; // page address in Main Memory to which
   page[PADDRESS-1:0] = temp_page[PADDRESS-1:0]; // page address in Main Memory to which
                                                 // data needs to be written
                                                 // data needs to be written
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't Write: Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't Write: Page No. %d is Protected, becase WPB is Low", page);
     disable MMPPB2_ ;
     disable MMPPB2_ ;
   end
   end
 
 
   compute_address; // even if byte_new-address is junk, we only need Page_Low_Boundary
   compute_address; // even if byte_new-address is junk, we only need Page_Low_Boundary
 
 
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   write_to_memory (2, page_boundary_low);
   write_to_memory (2, page_boundary_low);
   updating_memory = 1'b1;
   updating_memory = 1'b1;
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   updating_memory = 1'b0;
   updating_memory = 1'b0;
end
end
 
 
 
 
/******* Auto Page Rewrite Through Buffer 1 *****************/
/******* Auto Page Rewrite Through Buffer 1 *****************/
 
 
always @(APRB1)
always @(APRB1)
begin : APRB1_
begin : APRB1_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Auto Page Rewrite is not allowed");
     $display ("Device is busy. Auto Page Rewrite is not allowed");
     disable APRB1_ ;
     disable APRB1_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   transfer_to_buffer (1, page_boundary_low);
   transfer_to_buffer (1, page_boundary_low);
   updating_buffer1 = 1'b1;
   updating_buffer1 = 1'b1;
 
 
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't ReWrite: Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't ReWrite: Page No. %d is Protected, becase WPB is Low", page);
     #tEP updating_buffer1 = 1'b0;
     #tEP updating_buffer1 = 1'b0;
     disable APRB1_ ;
     disable APRB1_ ;
   end
   end
 
 
   updating_memory = 1'b1;
   updating_memory = 1'b1;
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   updating_buffer1 = 1'b0;
   updating_buffer1 = 1'b0;
   updating_memory = 1'b0;
   updating_memory = 1'b0;
   // NOTE:
   // NOTE:
   // We dont need to rewrite the data back into main-memory, as the 
   // We dont need to rewrite the data back into main-memory, as the 
   //        data is already available in the main-memory
   //        data is already available in the main-memory
   // This task was exactly same as MMPTB1T, except the delay-value
   // This task was exactly same as MMPTB1T, except the delay-value
   //      We could have easily used the same code as MMPTB1T, using 
   //      We could have easily used the same code as MMPTB1T, using 
   //      an if condition for delay-selection. However, still doing
   //      an if condition for delay-selection. However, still doing
   //      this way, so that the code for each opcode is independent
   //      this way, so that the code for each opcode is independent
   //      of anything else.
   //      of anything else.
end
end
 
 
 
 
/******* Auto Page Rewrite Through Buffer 2 *****************/
/******* Auto Page Rewrite Through Buffer 2 *****************/
 
 
always @(APRB2)
always @(APRB2)
begin : APRB2_
begin : APRB2_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Auto Page Rewrite is not allowed");
     $display ("Device is busy. Auto Page Rewrite is not allowed");
     disable APRB2_ ;
     disable APRB2_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress according to the parameters
        // within PageAddress according to the parameters
   compute_page_address;
   compute_page_address;
 
 
   get_data; // This is dont_care
   get_data; // This is dont_care
 
 
   compute_address; // even though, byte_new-address could be junk,
   compute_address; // even though, byte_new-address could be junk,
                    // we are only interested in Low page-boundaries,
                    // we are only interested in Low page-boundaries,
                    // which can be obtained correctly
                    // which can be obtained correctly
   @ (posedge CSB);
   @ (posedge CSB);
   transfer_to_buffer (2, page_boundary_low);
   transfer_to_buffer (2, page_boundary_low);
   updating_buffer2 = 1'b1;
   updating_buffer2 = 1'b1;
 
 
   if ((WPB == 1'b0) && (page < PROTECTED))
   if ((WPB == 1'b0) && (page < PROTECTED))
   begin
   begin
     $display ("Cann't ReWrite: Page No. %d is Protected, becase WPB is Low", page);
     $display ("Cann't ReWrite: Page No. %d is Protected, becase WPB is Low", page);
     #tEP updating_buffer2 = 1'b0;
     #tEP updating_buffer2 = 1'b0;
     disable APRB2_ ;
     disable APRB2_ ;
   end
   end
 
 
   RDYBSY_reg = 1'b1; // device is busy
   RDYBSY_reg = 1'b1; // device is busy
   status[7] = 1'b0;
   status[7] = 1'b0;
   updating_memory = 1'b1;
   updating_memory = 1'b1;
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   #tEP RDYBSY_reg = 1'b0; // device is now ready
   status[7] = 1'b1;
   status[7] = 1'b1;
   updating_buffer2 = 1'b0;
   updating_buffer2 = 1'b0;
   updating_memory = 1'b0;
   updating_memory = 1'b0;
   // NOTE:
   // NOTE:
   // We dont need to rewrite the data back into main-memory, as the 
   // We dont need to rewrite the data back into main-memory, as the 
   //        data is already available in the main-memory
   //        data is already available in the main-memory
   // This task was exactly same as MMPTB2T, except the delay-value
   // This task was exactly same as MMPTB2T, except the delay-value
   //      We could have easily used the same code as MMPTB2T, using 
   //      We could have easily used the same code as MMPTB2T, using 
   //      an if condition for delay-selection. However, still doing
   //      an if condition for delay-selection. However, still doing
   //      this way, so that the code for each opcode is independent
   //      this way, so that the code for each opcode is independent
   //      of anything else.
   //      of anything else.
end
end
 
 
 
 
/********* Status Register Read ********************/
/********* Status Register Read ********************/
 
 
always @(SR)
always @(SR)
begin: SR_
begin: SR_
  status_read = 1'b1; // reading status_reg
  status_read = 1'b1; // reading status_reg
  j = 8;
  j = 8;
   if (skip == 1'b1)
   if (skip == 1'b1)
     @(posedge SCK); // skip one SCK
     @(posedge SCK); // skip one SCK
  while (CSB == 1'b0)
  while (CSB == 1'b0)
  begin
  begin
    @(negedge SCK);
    @(negedge SCK);
    #tV ;
    #tV ;
    if (j > 0)
    if (j > 0)
       j = j-1;
       j = j-1;
    else
    else
       j = 7;
       j = 7;
    SO_reg=status[j];
    SO_reg=status[j];
    SO_on = 1'b1;
    SO_on = 1'b1;
    SO_reg = status[j];
    SO_reg = status[j];
  end // output next bit on next falling edge of SCK
  end // output next bit on next falling edge of SCK
  status_read = 1'b0; // status_reg read is over
  status_read = 1'b0; // status_reg read is over
 
 
end
end
 
 
always @(negedge RDYBSY_reg) // this block to take care of situations,
always @(negedge RDYBSY_reg) // this block to take care of situations,
                             // where status gets changed, while, it
                             // where status gets changed, while, it
                             // is being read.
                             // is being read.
                             // Applicable only in cases, where, device gets
                             // Applicable only in cases, where, device gets
                             // ready, from busy.
                             // ready, from busy.
   if (status_read == 1'b1)
   if (status_read == 1'b1)
      SO_reg = status[j];    // No harm, even if we have done this for other bits
      SO_reg = status[j];    // No harm, even if we have done this for other bits
                             // of status_reg
                             // of status_reg
 
 
 
 
/******* Main Memory Continuous Read ********************/
/******* Main Memory Continuous Read ********************/
 
 
always @(RWOPR)
always @(RWOPR)
begin : RWOPR_
begin : RWOPR_
   if (RDYBSY_reg == 1'b1) // device is already busy
   if (RDYBSY_reg == 1'b1) // device is already busy
   begin
   begin
     $display ("Device is busy. Main Memory Page Read is not allowed");
     $display ("Device is busy. Main Memory Page Read is not allowed");
     disable RWOPR_ ;
     disable RWOPR_ ;
   end
   end
         // if it comes here, means, the above if was false.
         // if it comes here, means, the above if was false.
   get_data;
   get_data;
   temp_reg1[7:0] = read_data [7:0];
   temp_reg1[7:0] = read_data [7:0];
   get_data;
   get_data;
 
 
        // Now that the two byte_news have been obtained, distribute it 
        // Now that the two byte_news have been obtained, distribute it 
        // within PageAddress and byte_new-address, according to 
        // within PageAddress and byte_new-address, according to 
        // the parameters.
        // the parameters.
   compute_page_address;
   compute_page_address;
   compute_byte_new_address;
   compute_byte_new_address;
 
 
      // next 8 bits always contain byte_new-address[7:0], and, so is
      // next 8 bits always contain byte_new-address[7:0], and, so is
      // not dependent on parameters
      // not dependent on parameters
   get_data;
   get_data;
   byte_new[7:0] = read_data[7:0];
   byte_new[7:0] = read_data[7:0];
 
 
   for (j=0; j<4; j=j+1)
   for (j=0; j<4; j=j+1)
      get_data ;  // these 32 bits are dont-care, and so have been discarded.
      get_data ;  // these 32 bits are dont-care, and so have been discarded.
 
 
   compute_address;
   compute_address;
   if (skip == 1'b1)
   if (skip == 1'b1)
     @(posedge SCK); // skip one SCK
     @(posedge SCK); // skip one SCK
   read_out_array ;
   read_out_array ;
end
end
 
 
 
 
/******** Posedge CSB. Stop all reading, recvng. commands/addresses etc. *********/
/******** Posedge CSB. Stop all reading, recvng. commands/addresses etc. *********/
 
 
always @(posedge CSB)
always @(posedge CSB)
begin
begin
  disable MMPR_; // MMPR will stop, if CSB goes high
  disable MMPR_; // MMPR will stop, if CSB goes high
  disable RWOPR_; // RWOPR will stop, if CSB goes high
  disable RWOPR_; // RWOPR will stop, if CSB goes high
 
 
  disable B1R_; // B1R will stop, if CSB goes high
  disable B1R_; // B1R will stop, if CSB goes high
 
 
  disable B2R_; // B2R will stop, if CSB goes high
  disable B2R_; // B2R will stop, if CSB goes high
 
 
  disable B1W_; // B1W will stop, if CSB goes high
  disable B1W_; // B1W will stop, if CSB goes high
 
 
  disable B2W_; // B2W will stop, if CSB goes high
  disable B2W_; // B2W will stop, if CSB goes high
 
 
  disable SR_; // Status reading should stop.
  disable SR_; // Status reading should stop.
  status_read = 1'b0;
  status_read = 1'b0;
 
 
  disable read_out; // Stop reading, NOW
  disable read_out; // Stop reading, NOW
  disable read_out_array;
  disable read_out_array;
  disable get_data; // Stop data retrieval
  disable get_data; // Stop data retrieval
  disable write_data; // Stop writing to buffers, NOW
  disable write_data; // Stop writing to buffers, NOW
 
 
  #tDIS SO_on = 1'b0;  // SO is now in high-impedance
  #tDIS SO_on = 1'b0;  // SO is now in high-impedance
end
end
 
 
 
 
/******** RESETB asserted. ******************/
/******** RESETB asserted. ******************/
 
 
always @(negedge RESETB)
always @(negedge RESETB)
begin
begin
                               // stop doing whatever you were doing
                               // stop doing whatever you were doing
  disable get_opcode;
  disable get_opcode;
  disable MMPR_;
  disable MMPR_;
  disable B1R_;
  disable B1R_;
  disable B2R_;
  disable B2R_;
  disable MMPTB1T_;
  disable MMPTB1T_;
  disable MMPTB2T_;
  disable MMPTB2T_;
  disable MMPTB1C_;
  disable MMPTB1C_;
  disable MMPTB2C_;
  disable MMPTB2C_;
  disable B1W_;
  disable B1W_;
  disable B2W_;
  disable B2W_;
  disable B1TMMPPWBIE_;
  disable B1TMMPPWBIE_;
  disable B2TMMPPWBIE_;
  disable B2TMMPPWBIE_;
  disable B1TMMPPWOBIE_;
  disable B1TMMPPWOBIE_;
  disable B2TMMPPWOBIE_;
  disable B2TMMPPWOBIE_;
  disable PE_;
  disable PE_;
  disable BE_;
  disable BE_;
  disable MMPPB1_;
  disable MMPPB1_;
  disable MMPPB2_;
  disable MMPPB2_;
  disable APRB1_;
  disable APRB1_;
  disable APRB2_;
  disable APRB2_;
                            // if you were in the middle of some prog. that part
                            // if you were in the middle of some prog. that part
                            //                  is now unknown.
                            //                  is now unknown.
  if (updating_buffer1 == 1'b1)
  if (updating_buffer1 == 1'b1)
  begin
  begin
    $display("RESETB asserted, when, updating Buffer1. Corrupting Buffer1");
    $display("RESETB asserted, when, updating Buffer1. Corrupting Buffer1");
    corrupt_buffer (1);
    corrupt_buffer (1);
    updating_buffer1 = 1'b0;
    updating_buffer1 = 1'b0;
  end
  end
 
 
  if (updating_buffer2 == 1'b1)
  if (updating_buffer2 == 1'b1)
  begin
  begin
    $display("RESETB asserted, when, updating Buffer2. Corrupting Buffer1");
    $display("RESETB asserted, when, updating Buffer2. Corrupting Buffer1");
    corrupt_buffer (2);
    corrupt_buffer (2);
    updating_buffer2 = 1'b0;
    updating_buffer2 = 1'b0;
  end
  end
 
 
  if (comparing == 1'b1)
  if (comparing == 1'b1)
  begin
  begin
    $display("RESETB asserted, when, comparing. Corrupting Status Bit 6");
    $display("RESETB asserted, when, comparing. Corrupting Status Bit 6");
    status[6] = 1'bx; // unknown
    status[6] = 1'bx; // unknown
    comparing = 1'b0;
    comparing = 1'b0;
  end
  end
 
 
  if (updating_memory == 1'b1)
  if (updating_memory == 1'b1)
  begin
  begin
    $display("RESETB asserted, when, updating memory. Corrupting Memory Page");
    $display("RESETB asserted, when, updating memory. Corrupting Memory Page");
    corrupt_memory ;
    corrupt_memory ;
    updating_memory = 1'b0;
    updating_memory = 1'b0;
  end
  end
 
 
  if (erasing_page == 1'b1)
  if (erasing_page == 1'b1)
  begin
  begin
    $display("RESETB asserted, when, erasing page. Corrupting Memory Page");
    $display("RESETB asserted, when, erasing page. Corrupting Memory Page");
    corrupt_memory ;
    corrupt_memory ;
    erasing_page = 1'b0;
    erasing_page = 1'b0;
  end
  end
 
 
  if (erasing_block == 1'b1)
  if (erasing_block == 1'b1)
  begin
  begin
    $display("RESETB asserted, when, erasing block. Corrupting Memory Block");
    $display("RESETB asserted, when, erasing block. Corrupting Memory Block");
    corrupt_block ;
    corrupt_block ;
    erasing_block = 1'b0;
    erasing_block = 1'b0;
  end
  end
 
 
 // SO also, needs to go to high-state, as well as the device needs to be Ready.
 // SO also, needs to go to high-state, as well as the device needs to be Ready.
 SO_on = 1'b0;
 SO_on = 1'b0;
 RDYBSY_reg = 1'b0;
 RDYBSY_reg = 1'b0;
 
 
end
end
 
 
 
 
/************************ TASKS / FUNCTIONS **************************/
/************************ TASKS / FUNCTIONS **************************/
 
 
/* get_data is a task to get 8 bits of data. This data could be an opcode,
/* get_data is a task to get 8 bits of data. This data could be an opcode,
address, data or anything. It just obtains 8 bits of data obtained on SI*/
address, data or anything. It just obtains 8 bits of data obtained on SI*/
 
 
task get_data;
task get_data;
 
 
integer i;
integer i;
 
 
begin
begin
   for (i=7; i>=0; i = i-1)
   for (i=7; i>=0; i = i-1)
   begin
   begin
      @(posedge SCK);
      @(posedge SCK);
      read_data[i] = SI;
      read_data[i] = SI;
   end
   end
end
end
 
 
endtask
endtask
 
 
 
 
/* compute_address is a task which to compute the current address,
/* compute_address is a task which to compute the current address,
as well as obtain the page boundaries */
as well as obtain the page boundaries */
 
 
task compute_address;
task compute_address;
 
 
begin
begin
  page_boundary_low = page * PAGESIZE;
  page_boundary_low = page * PAGESIZE;
  page_boundary_high = page_boundary_low + (PAGESIZE - 1);
  page_boundary_high = page_boundary_low + (PAGESIZE - 1);
  current_address = page_boundary_low + byte_new;
  current_address = page_boundary_low + byte_new;
  if (current_address < 540672)
  if (current_address < 540672)
      mem_no = 10;
      mem_no = 10;
  else if (current_address < 1081344)
  else if (current_address < 1081344)
      mem_no = 11;
      mem_no = 11;
  else if (current_address < 1622016)
  else if (current_address < 1622016)
      mem_no = 12;
      mem_no = 12;
  else if (current_address < 2162688)
  else if (current_address < 2162688)
      mem_no = 13;
      mem_no = 13;
  else if (current_address < 2703360)
  else if (current_address < 2703360)
      mem_no = 14;
      mem_no = 14;
  else if (current_address < 3244032)
  else if (current_address < 3244032)
      mem_no = 15;
      mem_no = 15;
  else if (current_address < 3784704)
  else if (current_address < 3784704)
      mem_no = 16;
      mem_no = 16;
  else mem_no = 17;
  else mem_no = 17;
end
end
 
 
endtask
endtask
 
 
/* read_out will read the output on SO pin. It can read contents of mainmemory, or,
/* read_out will read the output on SO pin. It can read contents of mainmemory, or,
either of the two buffers */
either of the two buffers */
 
 
task read_out ;
task read_out ;
input mem_type;
input mem_type;
input add;
input add;
input low;
input low;
input high;
input high;
 
 
integer mem_type;
integer mem_type;
integer add;
integer add;
integer low;
integer low;
integer high;
integer high;
 
 
integer i;
integer i;
 
 
begin
begin
  if (mem_type == 1)
  if (mem_type == 1)
     temp_reg1 = buffer1 [add];
     temp_reg1 = buffer1 [add];
  else if (mem_type == 2)
  else if (mem_type == 2)
     temp_reg1 = buffer2 [add];
     temp_reg1 = buffer2 [add];
 
 
  else if (mem_type == 10)
  else if (mem_type == 10)
     temp_reg1 = memory0 [add];
     temp_reg1 = memory0 [add];
  else if (mem_type == 11)
  else if (mem_type == 11)
     temp_reg1 = memory1 [add];
     temp_reg1 = memory1 [add];
  else if (mem_type == 12)
  else if (mem_type == 12)
     temp_reg1 = memory2 [add];
     temp_reg1 = memory2 [add];
  else if (mem_type == 13)
  else if (mem_type == 13)
     temp_reg1 = memory3 [add];
     temp_reg1 = memory3 [add];
  else if (mem_type == 14)
  else if (mem_type == 14)
     temp_reg1 = memory4 [add];
     temp_reg1 = memory4 [add];
  else if (mem_type == 15)
  else if (mem_type == 15)
     temp_reg1 = memory5 [add];
     temp_reg1 = memory5 [add];
  else if (mem_type == 16)
  else if (mem_type == 16)
     temp_reg1 = memory6 [add];
     temp_reg1 = memory6 [add];
  else if (mem_type == 17)
  else if (mem_type == 17)
     temp_reg1 = memory7 [add];
     temp_reg1 = memory7 [add];
  else
  else
     $display ("Int Error 1. This message should never appear. Something is wrong");
     $display ("Int Error 1. This message should never appear. Something is wrong");
 
 
   i = 7;
   i = 7;
   while (CSB == 1'b0) // continue transmitting, while, CSB is Low
   while (CSB == 1'b0) // continue transmitting, while, CSB is Low
   begin : CONTINUE_READING
   begin : CONTINUE_READING
      @(negedge SCK) ;
      @(negedge SCK) ;
      #tV SO_reg = temp_reg1[i];
      #tV SO_reg = temp_reg1[i];
          SO_on = 1'b1;
          SO_on = 1'b1;
      if (i == 0)
      if (i == 0)
        begin
        begin
          add = add + 1; // next byte_new
          add = add + 1; // next byte_new
          i = 7;
          i = 7;
          if (add > high)
          if (add > high)
              add = low; // Page rollover
              add = low; // Page rollover
 
 
          if (mem_type == 1)
          if (mem_type == 1)
             temp_reg1 = buffer1 [add];
             temp_reg1 = buffer1 [add];
          else if (mem_type == 2)
          else if (mem_type == 2)
             temp_reg1 = buffer2 [add];
             temp_reg1 = buffer2 [add];
 
 
          else if (mem_type == 10)
          else if (mem_type == 10)
             temp_reg1 = memory0 [add];
             temp_reg1 = memory0 [add];
          else if (mem_type == 11)
          else if (mem_type == 11)
             temp_reg1 = memory1 [add];
             temp_reg1 = memory1 [add];
          else if (mem_type == 12)
          else if (mem_type == 12)
             temp_reg1 = memory2 [add];
             temp_reg1 = memory2 [add];
          else if (mem_type == 13)
          else if (mem_type == 13)
             temp_reg1 = memory3 [add];
             temp_reg1 = memory3 [add];
          else if (mem_type == 14)
          else if (mem_type == 14)
             temp_reg1 = memory4 [add];
             temp_reg1 = memory4 [add];
          else if (mem_type == 15)
          else if (mem_type == 15)
             temp_reg1 = memory5 [add];
             temp_reg1 = memory5 [add];
          else if (mem_type == 16)
          else if (mem_type == 16)
             temp_reg1 = memory6 [add];
             temp_reg1 = memory6 [add];
          else if (mem_type == 17)
          else if (mem_type == 17)
             temp_reg1 = memory7 [add];
             temp_reg1 = memory7 [add];
 
 
        end
        end
      else
      else
        i = i - 1; // next bit
        i = i - 1; // next bit
 
 
   end // reading over, because CSB has gone high
   end // reading over, because CSB has gone high
end
end
 
 
endtask
endtask
 
 
/* task read_out_array is to read from main Memory, either in
/* task read_out_array is to read from main Memory, either in
          Continuous Mode, or, in Burst Mode */
          Continuous Mode, or, in Burst Mode */
 
 
task read_out_array ;
task read_out_array ;
 
 
integer i;
integer i;
integer temp_mem;
integer temp_mem;
integer temp_current;
integer temp_current;
integer temp_high;
integer temp_high;
integer temp_low;
integer temp_low;
integer temp_add;
integer temp_add;
 
 
begin
begin
  temp_mem = mem_no;
  temp_mem = mem_no;
  temp_high = page_boundary_high;
  temp_high = page_boundary_high;
  temp_low = page_boundary_low;
  temp_low = page_boundary_low;
  temp_add = current_address;
  temp_add = current_address;
 
 
  if (temp_mem == 10)
  if (temp_mem == 10)
     temp_reg1 = memory0 [temp_add];
     temp_reg1 = memory0 [temp_add];
  else if (temp_mem == 11)
  else if (temp_mem == 11)
     temp_reg1 = memory1 [temp_add];
     temp_reg1 = memory1 [temp_add];
  else if (temp_mem == 12)
  else if (temp_mem == 12)
     temp_reg1 = memory2 [temp_add];
     temp_reg1 = memory2 [temp_add];
  else if (temp_mem == 13)
  else if (temp_mem == 13)
     temp_reg1 = memory3 [temp_add];
     temp_reg1 = memory3 [temp_add];
  else if (temp_mem == 14)
  else if (temp_mem == 14)
     temp_reg1 = memory4 [temp_add];
     temp_reg1 = memory4 [temp_add];
  else if (temp_mem == 15)
  else if (temp_mem == 15)
     temp_reg1 = memory5 [temp_add];
     temp_reg1 = memory5 [temp_add];
  else if (temp_mem == 16)
  else if (temp_mem == 16)
     temp_reg1 = memory6 [temp_add];
     temp_reg1 = memory6 [temp_add];
  else if (temp_mem == 17)
  else if (temp_mem == 17)
     temp_reg1 = memory7 [temp_add];
     temp_reg1 = memory7 [temp_add];
  else
  else
     $display ("Int Error 1. This message should never appear. Something is wrong");
     $display ("Int Error 1. This message should never appear. Something is wrong");
 
 
   i = 7;
   i = 7;
   while (CSB == 1'b0) // continue transmitting, while, CSB is Low
   while (CSB == 1'b0) // continue transmitting, while, CSB is Low
   begin : CONTINUE_READING
   begin : CONTINUE_READING
      @(negedge SCK) ;
      @(negedge SCK) ;
      #tV SO_reg = temp_reg1[i];
      #tV SO_reg = temp_reg1[i];
          SO_on = 1'b1;
          SO_on = 1'b1;
      if (i == 0)
      if (i == 0)
        begin
        begin
          temp_add = temp_add + 1; // next byte_new
          temp_add = temp_add + 1; // next byte_new
          i = 7;
          i = 7;
          if (temp_add >= MEMSIZE)
          if (temp_add >= MEMSIZE)
          begin
          begin
              temp_add = 0; // Note that rollover occurs at end of memory,
              temp_add = 0; // Note that rollover occurs at end of memory,
              temp_high = PAGESIZE - 1; // and not at the end of the page
              temp_high = PAGESIZE - 1; // and not at the end of the page
              temp_low = 0;
              temp_low = 0;
          end
          end
          if (temp_add > temp_high) // going to next page
          if (temp_add > temp_high) // going to next page
          begin
          begin
             temp_high = temp_high + PAGESIZE;
             temp_high = temp_high + PAGESIZE;
             temp_low = temp_low + PAGESIZE;
             temp_low = temp_low + PAGESIZE;
          end
          end
 
 
          if (temp_add > 3784703)  // this block is a kludge to take
          if (temp_add > 3784703)  // this block is a kludge to take
             temp_mem = 17;        // care of multiple memory declarations
             temp_mem = 17;        // care of multiple memory declarations
          else if (temp_add > 3244031) // in the model, due to limitation
          else if (temp_add > 3244031) // in the model, due to limitation
             temp_mem = 16;            // of Verilog
             temp_mem = 16;            // of Verilog
          else if (temp_add > 2703359)
          else if (temp_add > 2703359)
             temp_mem = 15;
             temp_mem = 15;
          else if (temp_add > 2162687)
          else if (temp_add > 2162687)
             temp_mem = 14;
             temp_mem = 14;
          else if (temp_add > 1622015)
          else if (temp_add > 1622015)
             temp_mem = 13;
             temp_mem = 13;
          else if (temp_add > 1081343)
          else if (temp_add > 1081343)
             temp_mem = 12;
             temp_mem = 12;
          else if (temp_add > 540671)
          else if (temp_add > 540671)
             temp_mem = 11;
             temp_mem = 11;
          else temp_mem = 10;
          else temp_mem = 10;
 
 
          if (temp_mem == 10)
          if (temp_mem == 10)
             temp_reg1 = memory0 [temp_add];
             temp_reg1 = memory0 [temp_add];
          else if (temp_mem == 11)
          else if (temp_mem == 11)
             temp_reg1 = memory1 [temp_add];
             temp_reg1 = memory1 [temp_add];
          else if (temp_mem == 12)
          else if (temp_mem == 12)
             temp_reg1 = memory2 [temp_add];
             temp_reg1 = memory2 [temp_add];
          else if (temp_mem == 13)
          else if (temp_mem == 13)
             temp_reg1 = memory3 [temp_add];
             temp_reg1 = memory3 [temp_add];
          else if (temp_mem == 14)
          else if (temp_mem == 14)
             temp_reg1 = memory4 [temp_add];
             temp_reg1 = memory4 [temp_add];
          else if (temp_mem == 15)
          else if (temp_mem == 15)
             temp_reg1 = memory5 [temp_add];
             temp_reg1 = memory5 [temp_add];
          else if (temp_mem == 16)
          else if (temp_mem == 16)
             temp_reg1 = memory6 [temp_add];
             temp_reg1 = memory6 [temp_add];
          else if (temp_mem == 17)
          else if (temp_mem == 17)
             temp_reg1 = memory7 [temp_add];
             temp_reg1 = memory7 [temp_add];
 
 
        end
        end
      else
      else
        i = i - 1; // next bit
        i = i - 1; // next bit
   end // reading over, because CSB has gone high
   end // reading over, because CSB has gone high
end
end
 
 
endtask
endtask
 
 
 
 
/* transfer_to_buffer will transfer data into a buffer from a page of
/* transfer_to_buffer will transfer data into a buffer from a page of
main memory */
main memory */
 
 
/* transfer_to_buffer will transfer data into a buffer from a page of
/* transfer_to_buffer will transfer data into a buffer from a page of
main memory */
main memory */
 
 
task transfer_to_buffer ;
task transfer_to_buffer ;
input buf_type;
input buf_type;
input low;
input low;
 
 
integer buf_type;
integer buf_type;
integer low;
integer low;
 
 
integer i;
integer i;
 
 
begin
begin
       // Intentionally written this way: i.e. the for loop is within all if.
       // Intentionally written this way: i.e. the for loop is within all if.
       // Writing in alternative way would cause shorter code, but, significant
       // Writing in alternative way would cause shorter code, but, significant
       // increase in simulation time.
       // increase in simulation time.
  if (buf_type == 1)
  if (buf_type == 1)
  begin
  begin
    if (mem_no == 10)
    if (mem_no == 10)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer1[i] = memory0[low+i];
          buffer1[i] = memory0[low+i];
    else if (mem_no == 11)
    else if (mem_no == 11)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer1[i] = memory1[low+i];
          buffer1[i] = memory1[low+i];
    else if (mem_no == 12)
    else if (mem_no == 12)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer1[i] = memory2[low+i];
          buffer1[i] = memory2[low+i];
    else if (mem_no == 13)
    else if (mem_no == 13)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer1[i] = memory3[low+i];
          buffer1[i] = memory3[low+i];
    else if (mem_no == 14)
    else if (mem_no == 14)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer1[i] = memory4[low+i];
          buffer1[i] = memory4[low+i];
    else if (mem_no == 15)
    else if (mem_no == 15)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer1[i] = memory5[low+i];
          buffer1[i] = memory5[low+i];
    else if (mem_no == 16)
    else if (mem_no == 16)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer1[i] = memory6[low+i];
          buffer1[i] = memory6[low+i];
    else if (mem_no == 17)
    else if (mem_no == 17)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer1[i] = memory7[low+i];
          buffer1[i] = memory7[low+i];
    else $display ("Should Never reach here. Something is wrong");
    else $display ("Should Never reach here. Something is wrong");
  end
  end
 
 
  else if (buf_type == 2)
  else if (buf_type == 2)
  begin
  begin
    if (mem_no == 10)
    if (mem_no == 10)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer2[i] = memory0[low+i];
          buffer2[i] = memory0[low+i];
    else if (mem_no == 11)
    else if (mem_no == 11)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer2[i] = memory1[low+i];
          buffer2[i] = memory1[low+i];
    else if (mem_no == 12)
    else if (mem_no == 12)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer2[i] = memory2[low+i];
          buffer2[i] = memory2[low+i];
    else if (mem_no == 13)
    else if (mem_no == 13)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer2[i] = memory3[low+i];
          buffer2[i] = memory3[low+i];
    else if (mem_no == 14)
    else if (mem_no == 14)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer2[i] = memory4[low+i];
          buffer2[i] = memory4[low+i];
    else if (mem_no == 15)
    else if (mem_no == 15)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer2[i] = memory5[low+i];
          buffer2[i] = memory5[low+i];
    else if (mem_no == 16)
    else if (mem_no == 16)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer2[i] = memory6[low+i];
          buffer2[i] = memory6[low+i];
    else if (mem_no == 17)
    else if (mem_no == 17)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          buffer2[i] = memory7[low+i];
          buffer2[i] = memory7[low+i];
    else $display ("Should Never reach here. Something is wrong");
    else $display ("Should Never reach here. Something is wrong");
  end
  end
 
 
  else
  else
     $display ("Int Error 2. This message should never appear. Something is wrong");
     $display ("Int Error 2. This message should never appear. Something is wrong");
 
 
end
end
 
 
endtask
endtask
 
 
 
 
/* compare_with_buffer will compare data into a buffer against a page of
/* compare_with_buffer will compare data into a buffer against a page of
main memory */
main memory */
 
 
task compare_with_buffer ;
task compare_with_buffer ;
input buf_type;
input buf_type;
input low;
input low;
 
 
integer buf_type;
integer buf_type;
integer low;
integer low;
 
 
integer i, k;
integer i, k;
reg [7:0] tmp1, tmp2;
reg [7:0] tmp1, tmp2;
 
 
begin
begin
 
 
  status[6] = 1'b0;
  status[6] = 1'b0;
  if (buf_type == 1)
  if (buf_type == 1)
    for (i=0 ; i < PAGESIZE; i = i+1)
    for (i=0 ; i < PAGESIZE; i = i+1)
    begin : LOOP1
    begin : LOOP1
       if (mem_no == 10)
       if (mem_no == 10)
          tmp1 = memory0[low+i];
          tmp1 = memory0[low+i];
       else if (mem_no == 11)
       else if (mem_no == 11)
          tmp1 = memory1[low+i];
          tmp1 = memory1[low+i];
       else if (mem_no == 12)
       else if (mem_no == 12)
          tmp1 = memory2[low+i];
          tmp1 = memory2[low+i];
       else if (mem_no == 13)
       else if (mem_no == 13)
          tmp1 = memory3[low+i];
          tmp1 = memory3[low+i];
       else if (mem_no == 14)
       else if (mem_no == 14)
          tmp1 = memory4[low+i];
          tmp1 = memory4[low+i];
       else if (mem_no == 15)
       else if (mem_no == 15)
          tmp1 = memory5[low+i];
          tmp1 = memory5[low+i];
       else if (mem_no == 16)
       else if (mem_no == 16)
          tmp1 = memory6[low+i];
          tmp1 = memory6[low+i];
       else if (mem_no == 17)
       else if (mem_no == 17)
          tmp1 = memory7[low+i];
          tmp1 = memory7[low+i];
       else $display ("should never reach here. Something went wrong");
       else $display ("should never reach here. Something went wrong");
       tmp2 = buffer1[i];
       tmp2 = buffer1[i];
       for (k=0; k < 8; k = k+1)
       for (k=0; k < 8; k = k+1)
           if (tmp1[k] !== tmp2[k])
           if (tmp1[k] !== tmp2[k])
           begin  // detected miscompare. No need for further comparison
           begin  // detected miscompare. No need for further comparison
             status[6] = 1'b1;
             status[6] = 1'b1;
             disable LOOP1;
             disable LOOP1;
           end
           end
    end
    end
  else if (buf_type == 2)
  else if (buf_type == 2)
    for (i=0 ; i < PAGESIZE; i = i+1)
    for (i=0 ; i < PAGESIZE; i = i+1)
    begin : LOOP2
    begin : LOOP2
       if (mem_no == 10)
       if (mem_no == 10)
          tmp1 = memory0[low+i];
          tmp1 = memory0[low+i];
       else if (mem_no == 11)
       else if (mem_no == 11)
          tmp1 = memory1[low+i];
          tmp1 = memory1[low+i];
       else if (mem_no == 12)
       else if (mem_no == 12)
          tmp1 = memory2[low+i];
          tmp1 = memory2[low+i];
       else if (mem_no == 13)
       else if (mem_no == 13)
          tmp1 = memory3[low+i];
          tmp1 = memory3[low+i];
       else if (mem_no == 14)
       else if (mem_no == 14)
          tmp1 = memory4[low+i];
          tmp1 = memory4[low+i];
       else if (mem_no == 15)
       else if (mem_no == 15)
          tmp1 = memory5[low+i];
          tmp1 = memory5[low+i];
       else if (mem_no == 16)
       else if (mem_no == 16)
          tmp1 = memory6[low+i];
          tmp1 = memory6[low+i];
       else if (mem_no == 17)
       else if (mem_no == 17)
          tmp1 = memory7[low+i];
          tmp1 = memory7[low+i];
       else $display ("should never reach here. Something went wrong");
       else $display ("should never reach here. Something went wrong");
       tmp2 = buffer2[i];
       tmp2 = buffer2[i];
       for (k=0; k < 8; k = k+1)
       for (k=0; k < 8; k = k+1)
           if (tmp1[k] !== tmp2[k])
           if (tmp1[k] !== tmp2[k])
           begin  // detected miscompare. No need for further comparison
           begin  // detected miscompare. No need for further comparison
             status[6] = 1'b1;
             status[6] = 1'b1;
             disable LOOP2;
             disable LOOP2;
           end
           end
    end
    end
  else
  else
     $display ("Int error 3. This message should never appear. Something is wrong");
     $display ("Int error 3. This message should never appear. Something is wrong");
 
 
end
end
 
 
endtask
endtask
 
 
 
 
/* write_data will gat data from SI, and, write into device */
/* write_data will gat data from SI, and, write into device */
 
 
task write_data ;
task write_data ;
input buf_type;
input buf_type;
 
 
integer buf_type;
integer buf_type;
 
 
integer i;
integer i;
 
 
begin
begin
 
 
   while (CSB == 1'b0)
   while (CSB == 1'b0)
   begin
   begin
     for (i=7; i>=0; i=i-1)
     for (i=7; i>=0; i=i-1)
     begin
     begin
       @(posedge SCK);
       @(posedge SCK);
       temp_reg1[i] = SI;
       temp_reg1[i] = SI;
     end // Complete byte_new recvd. Now transfer the byte_new to memory/buffer
     end // Complete byte_new recvd. Now transfer the byte_new to memory/buffer
 
 
   if (buf_type == 1)  // Buffer 1
   if (buf_type == 1)  // Buffer 1
      buffer1[current_address] = temp_reg1;
      buffer1[current_address] = temp_reg1;
   else if (buf_type == 2) // Buffer 2
   else if (buf_type == 2) // Buffer 2
      buffer2[current_address] = temp_reg1;
      buffer2[current_address] = temp_reg1;
   else
   else
     $display ("Int error 4. This message should never appear. Something is wrong");
     $display ("Int error 4. This message should never appear. Something is wrong");
 
 
   current_address = current_address + 1;
   current_address = current_address + 1;
   if (current_address > page_boundary_high)
   if (current_address > page_boundary_high)
       current_address = page_boundary_low;
       current_address = page_boundary_low;
 
 
   end // continue writing. Note that parts of a byte_new will not be written.
   end // continue writing. Note that parts of a byte_new will not be written.
 
 
end
end
 
 
endtask
endtask
 
 
 
 
/* write_to_memory will transfer data from a buffer into a page of
/* write_to_memory will transfer data from a buffer into a page of
main memory */
main memory */
 
 
task write_to_memory ;
task write_to_memory ;
input buf_type;
input buf_type;
input low;
input low;
 
 
integer buf_type;
integer buf_type;
integer low;
integer low;
 
 
integer i;
integer i;
 
 
begin
begin
 
 
  if (buf_type == 1)
  if (buf_type == 1)
  begin
  begin
    if (mem_no == 10)
    if (mem_no == 10)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory0[low+i] = buffer1[i];
          memory0[low+i] = buffer1[i];
    else if (mem_no == 11)
    else if (mem_no == 11)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory1[low+i] = buffer1[i];
          memory1[low+i] = buffer1[i];
    else if (mem_no == 12)
    else if (mem_no == 12)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory2[low+i] = buffer1[i];
          memory2[low+i] = buffer1[i];
    else if (mem_no == 13)
    else if (mem_no == 13)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory3[low+i] = buffer1[i];
          memory3[low+i] = buffer1[i];
    else if (mem_no == 14)
    else if (mem_no == 14)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory4[low+i] = buffer1[i];
          memory4[low+i] = buffer1[i];
    else if (mem_no == 15)
    else if (mem_no == 15)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory5[low+i] = buffer1[i];
          memory5[low+i] = buffer1[i];
    else if (mem_no == 16)
    else if (mem_no == 16)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory6[low+i] = buffer1[i];
          memory6[low+i] = buffer1[i];
    else if (mem_no == 17)
    else if (mem_no == 17)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory7[low+i] = buffer1[i];
          memory7[low+i] = buffer1[i];
    else $display ("should never reach here. Something is wrong");
    else $display ("should never reach here. Something is wrong");
  end
  end
  else if (buf_type == 2)
  else if (buf_type == 2)
  begin
  begin
    if (mem_no == 10)
    if (mem_no == 10)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory0[low+i] = buffer2[i];
          memory0[low+i] = buffer2[i];
    else if (mem_no == 11)
    else if (mem_no == 11)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory1[low+i] = buffer2[i];
          memory1[low+i] = buffer2[i];
    else if (mem_no == 12)
    else if (mem_no == 12)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory2[low+i] = buffer2[i];
          memory2[low+i] = buffer2[i];
    else if (mem_no == 13)
    else if (mem_no == 13)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory3[low+i] = buffer2[i];
          memory3[low+i] = buffer2[i];
    else if (mem_no == 14)
    else if (mem_no == 14)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory4[low+i] = buffer2[i];
          memory4[low+i] = buffer2[i];
    else if (mem_no == 15)
    else if (mem_no == 15)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory5[low+i] = buffer2[i];
          memory5[low+i] = buffer2[i];
    else if (mem_no == 16)
    else if (mem_no == 16)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory6[low+i] = buffer2[i];
          memory6[low+i] = buffer2[i];
    else if (mem_no == 17)
    else if (mem_no == 17)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory7[low+i] = buffer2[i];
          memory7[low+i] = buffer2[i];
    else $display ("should never reach here. Something is wrong");
    else $display ("should never reach here. Something is wrong");
  end
  end
  else
  else
    $display ("Int error 4. This message should never appear. Something is wrong");
    $display ("Int error 4. This message should never appear. Something is wrong");
 
 
   page_status[page] = 1'b1; // this page is now not erased
   page_status[page] = 1'b1; // this page is now not erased
end
end
 
 
endtask
endtask
 
 
 
 
/* erase_page will erase a page of main memory */
/* erase_page will erase a page of main memory */
 
 
task erase_page ;
task erase_page ;
input low;
input low;
 
 
integer low;
integer low;
 
 
integer i;
integer i;
 
 
begin
begin
    if (mem_no == 10)
    if (mem_no == 10)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory0[low+i] = 8'hff;
          memory0[low+i] = 8'hff;
    else if (mem_no == 11)
    else if (mem_no == 11)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory1[low+i] = 8'hff;
          memory1[low+i] = 8'hff;
    else if (mem_no == 12)
    else if (mem_no == 12)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory2[low+i] = 8'hff;
          memory2[low+i] = 8'hff;
    else if (mem_no == 13)
    else if (mem_no == 13)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory3[low+i] = 8'hff;
          memory3[low+i] = 8'hff;
    else if (mem_no == 14)
    else if (mem_no == 14)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory4[low+i] = 8'hff;
          memory4[low+i] = 8'hff;
    else if (mem_no == 15)
    else if (mem_no == 15)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory5[low+i] = 8'hff;
          memory5[low+i] = 8'hff;
    else if (mem_no == 16)
    else if (mem_no == 16)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory6[low+i] = 8'hff;
          memory6[low+i] = 8'hff;
    else if (mem_no == 17)
    else if (mem_no == 17)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory7[low+i] = 8'hff;
          memory7[low+i] = 8'hff;
    else $display ("should never reach here. Something is wrong");
    else $display ("should never reach here. Something is wrong");
 
 
   page_status[page] = 1'b0; // this page is now erased
   page_status[page] = 1'b0; // this page is now erased
end
end
 
 
endtask
endtask
 
 
 
 
/* corrupt_buffer will corrupt the entire buffer */
/* corrupt_buffer will corrupt the entire buffer */
 
 
task corrupt_buffer ;
task corrupt_buffer ;
input buf_type;
input buf_type;
 
 
integer buf_type;
integer buf_type;
 
 
integer i;
integer i;
 
 
begin
begin
 
 
  if (buf_type == 1)
  if (buf_type == 1)
    for (i=0 ; i < PAGESIZE; i = i+1)
    for (i=0 ; i < PAGESIZE; i = i+1)
       buffer1[i] = 8'hx;
       buffer1[i] = 8'hx;
  else if (buf_type == 2)
  else if (buf_type == 2)
    for (i=0 ; i < PAGESIZE; i = i+1)
    for (i=0 ; i < PAGESIZE; i = i+1)
       buffer2[i] = 8'hx;
       buffer2[i] = 8'hx;
  else
  else
     $display ("Int Error 2. This message should never appear. Something is wrong");
     $display ("Int Error 2. This message should never appear. Something is wrong");
 
 
end
end
 
 
endtask
endtask
 
 
 
 
/* corrupt_memory will corrupt a page of memory */
/* corrupt_memory will corrupt a page of memory */
 
 
task corrupt_memory ;
task corrupt_memory ;
 
 
integer i;
integer i;
 
 
begin
begin
    if (mem_no == 10)
    if (mem_no == 10)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory0[page_boundary_low+i] = 8'hx;
          memory0[page_boundary_low+i] = 8'hx;
    else if (mem_no == 11)
    else if (mem_no == 11)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory1[page_boundary_low+i] = 8'hx;
          memory1[page_boundary_low+i] = 8'hx;
    else if (mem_no == 12)
    else if (mem_no == 12)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory2[page_boundary_low+i] = 8'hx;
          memory2[page_boundary_low+i] = 8'hx;
    else if (mem_no == 13)
    else if (mem_no == 13)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory3[page_boundary_low+i] = 8'hx;
          memory3[page_boundary_low+i] = 8'hx;
    else if (mem_no == 14)
    else if (mem_no == 14)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory4[page_boundary_low+i] = 8'hx;
          memory4[page_boundary_low+i] = 8'hx;
    else if (mem_no == 15)
    else if (mem_no == 15)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory5[page_boundary_low+i] = 8'hx;
          memory5[page_boundary_low+i] = 8'hx;
    else if (mem_no == 16)
    else if (mem_no == 16)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory6[page_boundary_low+i] = 8'hx;
          memory6[page_boundary_low+i] = 8'hx;
    else if (mem_no == 17)
    else if (mem_no == 17)
       for (i=0 ; i < PAGESIZE; i = i+1)
       for (i=0 ; i < PAGESIZE; i = i+1)
          memory7[page_boundary_low+i] = 8'hx;
          memory7[page_boundary_low+i] = 8'hx;
    else $display ("should never reach here. something is wrong");
    else $display ("should never reach here. something is wrong");
 
 
   page_status[page] = 1'b1; // Actually, sometimes, the status of this page is
   page_status[page] = 1'b1; // Actually, sometimes, the status of this page is
                             // unknown. But, using UnErased, is also OK here.
                             // unknown. But, using UnErased, is also OK here.
                             // Because, either way, user has to erase, in order
                             // Because, either way, user has to erase, in order
                             // to Program the page
                             // to Program the page
end
end
 
 
endtask
endtask
 
 
 
 
/* corrupt_block will corrupt a block (i.e. 8 pages) of memory */
/* corrupt_block will corrupt a block (i.e. 8 pages) of memory */
 
 
task corrupt_block ;
task corrupt_block ;
 
 
integer i;
integer i;
 
 
begin
begin
    if (mem_no == 10)
    if (mem_no == 10)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
          memory0[page_boundary_low+i] = 8'hx; // corrupted 8 pages
          memory0[page_boundary_low+i] = 8'hx; // corrupted 8 pages
    else if (mem_no == 11)
    else if (mem_no == 11)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
          memory1[page_boundary_low+i] = 8'hx; // corrupted 8 pages
          memory1[page_boundary_low+i] = 8'hx; // corrupted 8 pages
    else if (mem_no == 12)
    else if (mem_no == 12)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
          memory2[page_boundary_low+i] = 8'hx; // corrupted 8 pages
          memory2[page_boundary_low+i] = 8'hx; // corrupted 8 pages
    else if (mem_no == 13)
    else if (mem_no == 13)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
          memory3[page_boundary_low+i] = 8'hx; // corrupted 8 pages
          memory3[page_boundary_low+i] = 8'hx; // corrupted 8 pages
    else if (mem_no == 14)
    else if (mem_no == 14)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
          memory4[page_boundary_low+i] = 8'hx; // corrupted 8 pages
          memory4[page_boundary_low+i] = 8'hx; // corrupted 8 pages
    else if (mem_no == 15)
    else if (mem_no == 15)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
          memory5[page_boundary_low+i] = 8'hx; // corrupted 8 pages
          memory5[page_boundary_low+i] = 8'hx; // corrupted 8 pages
    else if (mem_no == 16)
    else if (mem_no == 16)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
          memory6[page_boundary_low+i] = 8'hx; // corrupted 8 pages
          memory6[page_boundary_low+i] = 8'hx; // corrupted 8 pages
    else if (mem_no == 17)
    else if (mem_no == 17)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
       for (i=0 ; i < PAGESIZE*8; i = i+1)
          memory7[page_boundary_low+i] = 8'hx; // corrupted 8 pages
          memory7[page_boundary_low+i] = 8'hx; // corrupted 8 pages
    else $display ("should never reach here. Something is wrong");
    else $display ("should never reach here. Something is wrong");
 
 
    for (i=0 ; i < 8; i = i+1)
    for (i=0 ; i < 8; i = i+1)
       page_status[page+i] = 1'b1; // Actually, sometimes, the status of this page is
       page_status[page+i] = 1'b1; // Actually, sometimes, the status of this page is
                                   //   unknown. But, using UnErased, is also OK here.
                                   //   unknown. But, using UnErased, is also OK here.
                                   //   Because, either way, user has to erase, in order
                                   //   Because, either way, user has to erase, in order
                                   //   to Program the page
                                   //   to Program the page
end
end
 
 
endtask
endtask
 
 
 
 
/* Task to compute page address */
/* Task to compute page address */
 
 
task compute_page_address;
task compute_page_address;
begin
begin
   page = 0; // zero out the redundant bits of 'page'
   page = 0; // zero out the redundant bits of 'page'
   case (PADDRESS)
   case (PADDRESS)
      13 : begin
      13 : begin
             page [12:6] = temp_reg1[6:0] ;
             page [12:6] = temp_reg1[6:0] ;
             page [5:0] = read_data[7:2] ;
             page [5:0] = read_data[7:2] ;
           end
           end
      12 : begin
      12 : begin
             if (status[5:3] == 3'b100)
             if (status[5:3] == 3'b100)
             begin
             begin
               page [11:7] = temp_reg1[4:0] ;
               page [11:7] = temp_reg1[4:0] ;
               page [6:0] = read_data[7:1] ;
               page [6:0] = read_data[7:1] ;
             end
             end
             if (status[5:3] == 3'b101)
             if (status[5:3] == 3'b101)
             begin
             begin
               page [11:6] = temp_reg1[5:0] ;
               page [11:6] = temp_reg1[5:0] ;
               page [5:0] = read_data[7:2] ;
               page [5:0] = read_data[7:2] ;
             end
             end
           end
           end
      11 : begin
      11 : begin
             page [10:7] = temp_reg1[3:0] ;
             page [10:7] = temp_reg1[3:0] ;
             page [6:0] = read_data[7:1] ;
             page [6:0] = read_data[7:1] ;
           end
           end
      10 : begin
      10 : begin
             page [9:7] = temp_reg1[2:0] ;
             page [9:7] = temp_reg1[2:0] ;
             page [6:0] = read_data[7:1] ;
             page [6:0] = read_data[7:1] ;
           end
           end
       9 : begin
       9 : begin
             page [8:7] = temp_reg1[1:0] ;
             page [8:7] = temp_reg1[1:0] ;
             page [6:0] = read_data[7:1] ;
             page [6:0] = read_data[7:1] ;
           end
           end
   endcase
   endcase
end
end
endtask
endtask
 
 
/* Task to compute starting byte_new address */
/* Task to compute starting byte_new address */
 
 
task compute_byte_new_address;
task compute_byte_new_address;
begin
begin
   case (BADDRESS)
   case (BADDRESS)
      10 : byte_new[9:8] = read_data[1:0] ;
      10 : byte_new[9:8] = read_data[1:0] ;
       9 : byte_new[8]   = read_data[0] ;
       9 : byte_new[8]   = read_data[0] ;
   endcase
   endcase
end
end
endtask
endtask
 
 
/* SPECIFY BLOCK */
/* SPECIFY BLOCK */
 
 
specify  /* all timing checks */
specify  /* all timing checks */
 
 
`ifdef device1M
`ifdef device1M
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tWH = 35;
specparam tWH = 35;
specparam tWL = 35;
specparam tWL = 35;
specparam tCS = 250;
specparam tCS = 250;
specparam tCSS = 250;
specparam tCSS = 250;
specparam tCSH = 250;
specparam tCSH = 250;
specparam tCSB = 200;
specparam tCSB = 200;
specparam tSU = 10;
specparam tSU = 10;
specparam tH = 20;
specparam tH = 20;
specparam tHO = 0;
specparam tHO = 0;
specparam tRST = 10000;
specparam tRST = 10000;
specparam tREC = 1000;
specparam tREC = 1000;
specparam tBAR = 200;
specparam tBAR = 200;
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tBRBD = 1000;
specparam tBRBD = 1000;
`endif
`endif
 
 
`ifdef device2M
`ifdef device2M
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tWH = 35;
specparam tWH = 35;
specparam tWL = 35;
specparam tWL = 35;
specparam tCS = 250;
specparam tCS = 250;
specparam tCSS = 250;
specparam tCSS = 250;
specparam tCSH = 250;
specparam tCSH = 250;
specparam tCSB = 200;
specparam tCSB = 200;
specparam tSU = 10;
specparam tSU = 10;
specparam tH = 20;
specparam tH = 20;
specparam tHO = 0;
specparam tHO = 0;
specparam tRST = 10000;
specparam tRST = 10000;
specparam tREC = 1000;
specparam tREC = 1000;
specparam tBAR = 200;
specparam tBAR = 200;
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tBRBD = 1000;
specparam tBRBD = 1000;
`endif
`endif
 
 
`ifdef device4M
`ifdef device4M
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tWH = 35;
specparam tWH = 35;
specparam tWL = 35;
specparam tWL = 35;
specparam tCS = 250;
specparam tCS = 250;
specparam tCSS = 250;
specparam tCSS = 250;
specparam tCSH = 250;
specparam tCSH = 250;
specparam tCSB = 200;
specparam tCSB = 200;
specparam tSU = 10;
specparam tSU = 10;
specparam tH = 20;
specparam tH = 20;
specparam tHO = 0;
specparam tHO = 0;
specparam tRST = 10000;
specparam tRST = 10000;
specparam tREC = 1000;
specparam tREC = 1000;
specparam tBAR = 200;
specparam tBAR = 200;
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tBRBD = 1000;
specparam tBRBD = 1000;
`endif
`endif
 
 
`ifdef device8M
`ifdef device8M
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tWH = 35;
specparam tWH = 35;
specparam tWL = 35;
specparam tWL = 35;
specparam tCS = 250;
specparam tCS = 250;
specparam tCSS = 250;
specparam tCSS = 250;
specparam tCSH = 250;
specparam tCSH = 250;
specparam tCSB = 200;
specparam tCSB = 200;
specparam tSU = 10;
specparam tSU = 10;
specparam tH = 20;
specparam tH = 20;
specparam tHO = 0;
specparam tHO = 0;
specparam tRST = 10000;
specparam tRST = 10000;
specparam tREC = 1000;
specparam tREC = 1000;
specparam tBAR = 200;
specparam tBAR = 200;
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tBRBD = 1000;
specparam tBRBD = 1000;
`endif
`endif
 
 
`ifdef device16M
`ifdef device16M
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tWH = 35;
specparam tWH = 35;
specparam tWL = 35;
specparam tWL = 35;
specparam tCS = 250;
specparam tCS = 250;
specparam tCSS = 250;
specparam tCSS = 250;
specparam tCSH = 250;
specparam tCSH = 250;
specparam tCSB = 200;
specparam tCSB = 200;
specparam tSU = 10;
specparam tSU = 10;
specparam tH = 20;
specparam tH = 20;
specparam tHO = 0;
specparam tHO = 0;
specparam tRST = 10000;
specparam tRST = 10000;
specparam tREC = 1000;
specparam tREC = 1000;
specparam tBAR = 200;
specparam tBAR = 200;
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tBRBD = 1000;
specparam tBRBD = 1000;
`endif
`endif
 
 
`ifdef device32M
`ifdef device32M
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tSCK = 77  ; // SCK time-period. 10e9/fSCK
specparam tWH = 35;
specparam tWH = 35;
specparam tWL = 35;
specparam tWL = 35;
specparam tCS = 250;
specparam tCS = 250;
specparam tCSS = 250;
specparam tCSS = 250;
specparam tCSH = 250;
specparam tCSH = 250;
specparam tCSB = 200;
specparam tCSB = 200;
specparam tSU = 10;
specparam tSU = 10;
specparam tH = 20;
specparam tH = 20;
specparam tHO = 0;
specparam tHO = 0;
specparam tRST = 10000;
specparam tRST = 10000;
specparam tREC = 1000;
specparam tREC = 1000;
specparam tBAR = 200;
specparam tBAR = 200;
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tCAR1 = 200; // this is same as tCAR, but, is needed twice
specparam tBRBD = 1000;
specparam tBRBD = 1000;
`endif
`endif
 
 
  // SCK related
  // SCK related
  $period(posedge SCK, tSCK); // SCK period is checked between
  $period(posedge SCK, tSCK); // SCK period is checked between
  $period(negedge SCK, tSCK); // rise-to-rise, as well as fall-to-fall
  $period(negedge SCK, tSCK); // rise-to-rise, as well as fall-to-fall
  $width(posedge SCK, tWH); // High PulseWidth
  $width(posedge SCK, tWH); // High PulseWidth
  $width(negedge SCK, tWL); // Low PulseWidth
  $width(negedge SCK, tWL); // Low PulseWidth
 
 
  // CSB related
  // CSB related
  $width(posedge CSB, tCS); // CSB Min. High
  $width(posedge CSB, tCS); // CSB Min. High
  $setup(CSB,posedge SCK, tCSS); // CSB setup time
  $setup(CSB,posedge SCK, tCSS); // CSB setup time
  $hold(posedge SCK, CSB, tCSH); // CSB hold time
  $hold(posedge SCK, CSB, tCSH); // CSB hold time
 
 
  // SI related. Being checked, only when CSB is Low
  // SI related. Being checked, only when CSB is Low
   $setup(SI, posedge SCK &&& ~CSB, tSU); // SI setup time
   $setup(SI, posedge SCK &&& ~CSB, tSU); // SI setup time
   $hold(posedge SCK &&& ~CSB, SI, tH); // SI hold time
   $hold(posedge SCK &&& ~CSB, SI, tH); // SI hold time
 
 
  // RESETB related
  // RESETB related
  $width(negedge RESETB, tRST); // RESETB Low Width
  $width(negedge RESETB, tRST); // RESETB Low Width
  $recovery(posedge SCK, RESETB, tREC); // RESETB Recovery 
  $recovery(posedge SCK, RESETB, tREC); // RESETB Recovery 
 
 
endspecify
endspecify
 
 
endmodule
endmodule
 
 
//`include "test_sequence2.v"
//`include "test_sequence2.v"
 
 

powered by: WebSVN 2.1.0

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