`timescale 1ns / 10 ps
//Filename: AT24C02B_rev_F_2008
// AT24C Device Family
// Note: Compiler directives are used to adapt the model to a particular
// device of the family.
// Note: Choose VERBOSE 0 to suppress troubleshooting messages.
// Dates of Revisions:
// m.d. ciletti 03/05/03
// m.d. ciletti 04/28/2006
// m.d. ciletti 05/30/2008
// B. Morgan 7/23/2008
// m.d. ciletti 7/26/2008
// Summary of Revisions
// Pre-2008 Modified to handle the following device functionality:
// (1) Detects toggling of SDA under SCL = 1 and cancels the START condition
// if the sequence ends with a STOP condition.
// (2) Detects and recovers from a random START condition, i.e. if a start
// condition appears anywhere in the data transmission the machine resets
// itself to begin receiving a device address byte.
// (3) Detects a sequence of 9 clocks with SDA held high and resets the
// machine to await a START condition. The address register of the machine
// is not affected by the reset operation.
// (4) Corrects an occurrence of an incorrect device label for the
// AT24C1024 device.
// (5) Includes address code for the P bits (had been removed for testing)
// 05/30/2008 Modified to deal with infinite loop upon time out for page
// write.
// 05/30/2008 Modified to provide additional documentation.
// 7/23/2008 Added 24C512B 1.8v 400khz and 2.5v 1Mhz timing sets.
// 7/26/2008 Modified to handle protocol violation with WP (write
protection)
// and provide additional documentation.
// Required reset of Valid_Address_flag.
// Corrected code entries for AT24C512B.
/////////////////////////////////////////////////////////////////////
///////
//
/////////////////////////////////////////////////////////////////////
///////
DEVICE SELECTION
`define WANT_VERBOSE 1
// Slave address formats
//
//
//
//
//
//
//
//
//
//
//
1010_0_A1_P0_R/W
1010_0_A1_A0_R/W
1010_0_A1_A0_R/W
1010_0_A1_A0_R/W
1010_A2_A1_A0_R/W
1010_A2_A2_A0_R/W
1010_P1_P1_P0_R/W
1010_A2_P1_P0_R/W
1010_A2_A1_P0_R/W
1010_A2_A1_A0_R/W
1010_A2_A1_A0_R/W
1M
512K
256K
128K
64K
32K
16K
8K
4K
2K
1K
// To configure the model, edit the comments of the compiler
// directives as specfifed below :
// (1) remove // from the `define line of the selected device
// (2) remove // to select timing parameters
// (3) set the SLAVE_ADDRESS (REQUIRED)
// (Arbitrary addresses are used below for testing)
// Be sure that the test bench is adapted to the particular model
// No further action needed.
(OPTIONAL)
(REQUIRED)
//`define AT24C1024
//`define AT24C512B
// define AT24C512
//`define AT24C256
//`define AT24C128
//`define AT24C64A
//`define AT24C32A
//`define AT24C16A
//`define AT24C08A
//`define AT24C04A
`define AT24C02A
//`define AT24C01A
//`define AT24C64
//`define AT24C32
//`define AT24C08
//`define AT24C04
//`define AT24C02
//`define AT34C02
// Options for timing parameters
//`define WANT_AT24C1024__4_5__5_5V_TIMING
//`define WANT_AT24C1024__2_7__5_5V_TIMING
//`define WANT_AT24C_01A_02_04_08_16__2_7__2_5__1_8_VOLT_TIMING
`define WANT_AT24C_01A_02_04_08_16__5_VOLT_TIMING
//`define WANT_AT24C_02A_04A_08A_16A__1_8_V_TIMING
//`define WANT_AT24C_02A_04A_08A__2_5V__2_7V_TIMING
//`define WANT_AT24C_16A__2_5V_TIMING
//`define WANT_AT24C_02A_04A_08A_16A__5V_TIMING
//`define WANT_AT24C512B__1_8V_TIMING
//`define WANT_AT24C512B__2_5V_TIMING
//`define WANT_AT24C512__1_8_V_TIMING
//`define WANT_AT24C512__2_7V_TIMING
//`define WANT_AT24C512__5V_TIMING
//`define WANT_AT24C128_256__1_8_V_TIMING
//`define WANT_AT24C128_256__2_5V_TIMING
//`define WANT_AT24C128_256__5V_TIMING
//`define WANT_AT34C02__1_8_VOLT_TIMING
//`define WANT_AT34C02__2_7__5_0_VOLT_TIMING
`ifdef AT24C1024
module
AT24C1024 (SDA, SCL, WP);
`endif
`ifdef AT24C512B
module
AT24C512B (SDA, SCL, WP);
`endif
`ifdef AT24C512
module
AT24C512 (SDA, SCL, WP);
`endif
`ifdef AT24C256
module
AT24C256 (SDA, SCL, WP);
`endif
`ifdef AT24C128
module
AT24C128 (SDA, SCL, WP);
`endif
`ifdef AT24C64A
module
AT24C64 (SDA, SCL, WP);
`endif
`ifdef AT24C32A
module
AT24C32 (SDA, SCL, WP);
`endif
`ifdef AT24C16A
module
AT24C16A (SDA, SCL, WP);
`endif
`ifdef AT24C08A
module
AT24C08A (SDA, SCL, WP);
`endif
`ifdef AT24C04A
module
AT24C04 (SDA, SCL, WP);
`endif
`ifdef AT24C02A
module
AT24C02A (SDA, SCL, WP);
`endif
`ifdef AT24C01A
module
AT24C01A (SDA, SCL, WP);
`endif
`ifdef AT24C64
module
AT24C64 (SDA, SCL, WP);
`endif
`ifdef AT24C32
module
AT24C32 (SDA, SCL, WP);
`endif
`ifdef AT24C16
module
AT24C16 (SDA, SCL, WP);
`endif
`ifdef AT24C08
module
AT24C08 (SDA, SCL, WP);
`endif
`ifdef AT24C04
module
AT24C04 (SDA, SCL, WP);
`endif
`ifdef AT24C02
module
AT24C02 (SDA, SCL, WP);
`endif
`ifdef AT34C02
module
AT34C02 (SDA, SCL, WP);
`endif
inout SDA;
Bi-directional serial data
input SCL;
input WP;
protection
//
// Serial clock
// Write
/////////////////////////////////////////////////////////////////////
////////
////////////////////////////// DEVICE CONFIGURATION
///////////////////////
// Slave address formats
//
//
//
//
//
//
//
//
//
//
//
1010_0_A1_P0_R/W
1010_0_A1_A0_R/W
1010_0_A1_A0_R/W
1010_0_A1_A0_R/W
1010_A2_A1_A0_R/W
1010_A2_A2_A0_R/W
1010_P1_P1_P0_R/W
1010_A2_P1_P0_R/W
1010_A2_A1_P0_R/W
1010_A2_A1_A0_R/W
1010_A2_A1_A0_R/W
1M
512K
256K
128K
64K
32K
16K
8K
4K
2K
1K
// The following parameters configure the device.
// The A2_A1_A0 of the slave addresses are arbitrary for the
// purpose of testing the model.
// device address, together with the appropriate memory address bits
// P2_P1_P0, as needed.
A testbench must send the indicated
//AT24C1024, 512 pages at 256 bytes/page, 17 address bits
`ifdef AT24C1024
parameter MEM_SIZE = 131072;
parameter ADDR_SIZE = 17;
parameter WORD_ADDR_SIZE = 8;
parameter SLAVE_ADDRESS = 6'b1010_00; // Testbench provides P0 and R/W
bits
`endif
// AT24C512B, 512 pages at 128 bytes/page, 16 address bits
`ifdef AT24C512B
parameter MEM_SIZE = 65536;
parameter ADDR_SIZE = 16;
parameter WORD_ADDR_SIZE = 7;
parameter SLAVE_ADDRESS = 7'b1010_011; // Testbench provides R/W bit
`endif
// AT24C512, 512 pages at 128 bytes/page, 16 address bits
`ifdef AT24C512
parameter MEM_SIZE = 65536;
parameter ADDR_SIZE = 16;
parameter WORD_ADDR_SIZE = 7;
parameter SLAVE_ADDRESS = 7'b1010_011; // Testbench provides R/W bit
`endif
// AT24C256, 512 pages at 64 bytes/page, 15 address bits
`ifdef AT24C256
parameter MEM_SIZE = 32768;
parameter ADDR_SIZE = 15;
parameter WORD_ADDR_SIZE = 6;
parameter SLAVE_ADDRESS = 7'b1010_011; // Testbench provides R/W bit
`endif
// AT24C128, 256 pages at 64 bytes/page, 14 address bits
`ifdef AT24C128
parameter MEM_SIZE = 16384;
parameter ADDR_SIZE = 14;
parameter WORD_ADDR_SIZE = 6;
parameter SLAVE_ADDRESS = 7'b1010_011; // Testbench provides R/W bit
`endif
// AT24C64, 256 pages at 32 bytes/page, 13 address bits
`ifdef AT24C64
parameter MEM_SIZE = 8192;
parameter ADDR_SIZE = 13;
parameter WORD_ADDR_SIZE = 5;
parameter SLAVE_ADDRESS = 7'b1010_111; // Testbench provides R/W bit
`endif
// AT24C64A, 256 pages at 32 bytes/page, 13 address bits
`ifdef AT24C64A
parameter MEM_SIZE = 8192;
parameter ADDR_SIZE = 13;
parameter WORD_ADDR_SIZE = 5;
parameter SLAVE_ADDRESS = 7'b1010_111; // Testbench provides R/W bit
`endif
// AT24C32, 128 pages at 32 bytes/page, 12 address bits
`ifdef AT24C32
parameter MEM_SIZE = 4096;
parameter ADDR_SIZE = 12;
parameter WORD_ADDR_SIZE = 5;
parameter SLAVE_ADDRESS = 7'b1010_101; // Testbench provides R/W bit
`endif
// AT24C32A, 128 pages at 32 bytes/page, 12 address bits
`ifdef AT24C32A
parameter MEM_SIZE = 4096;
parameter ADDR_SIZE = 12;
parameter WORD_ADDR_SIZE = 5;
parameter SLAVE_ADDRESS = 7'b1010_101; // Testbench provides R/W bit
`endif
// AT24C16, 128 pages at 16 bytes/page, 11 address bits
`ifdef AT24C16
parameter MEM_SIZE = 2048;
parameter ADDR_SIZE = 11;
parameter WORD_ADDR_SIZE = 4;
parameter SLAVE_ADDRESS = 4'b1010; // Testbench provides P2_P1_P0_R/W
bits
`endif
// AT24C16A, 128 pages at 16 bytes/page, 11 address bits
`ifdef AT24C16A
parameter MEM_SIZE = 2048;
parameter ADDR_SIZE = 11;
parameter WORD_ADDR_SIZE = 4;
parameter SLAVE_ADDRESS = 4'b1010; // Testbench provides P2_P1_P0_R/W
bits
`endif
// AT24C08, 64 pages at 16 bytes/page, 10 address bits
`ifdef AT24C08
parameter MEM_SIZE = 1024;
parameter ADDR_SIZE = 10;
parameter WORD_ADDR_SIZE = 4;
parameter SLAVE_ADDRESS = 5'b1010_0; // Testbench provides P1_P0_R/W
bits
`endif
// AT24C08A, 64 pages at 16 bytes/page, 10 address bits
`ifdef AT24C08A
parameter MEM_SIZE = 1024;
parameter ADDR_SIZE = 10;
parameter WORD_ADDR_SIZE = 4;
parameter SLAVE_ADDRESS = 5'b1010_0; // Testbench provides P1_P0_R/W
bits
`endif
// AT24C04, 32 pages at 16 bytes/page, 9 address bits
`ifdef AT24C04
parameter MEM_SIZE = 512;
parameter ADDR_SIZE = 9;
parameter WORD_ADDR_SIZE = 4;
parameter SLAVE_ADDRESS = 6'b1010_00; // Testbench provides P0_R/W bits
`endif
// AT24C04A, 32 pages at 16 bytes/page, 9 address bits
`ifdef AT24C04A
parameter MEM_SIZE = 512;
parameter ADDR_SIZE = 9;
parameter WORD_ADDR_SIZE = 4;
parameter SLAVE_ADDRESS = 6'b1010_00; // Testbench provides P0_R/W bits
`endif