⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at24c02.v

📁 at24c0x读写控制模块 支持单字节读写和页读写
💻 V
📖 第 1 页 / 共 2 页
字号:
//**********************************************************************//**********************************************************************`timescale 1ns / 10 ps//05-01-2002 Bryce Morgan//AT24C02 Verilog Model //This model was developed to accurately describe the functional behavior//of the Atmel Serial EEPROM Product AT24C02.module  AT24C02(  sda,  scl,  wp);   inout sda;						// Serial datainput scl;						// Serial clockinput wp;						     // Write protectionparameter DEVICE      = "AT24C02";      // Device nameparameter Device_Address = 7'b1010000;	// Device Addressparameter MEM_SIZE     = 256 ;           // Number of bytes in memoryparameter PAGE_SIZE    =  8 ;            // Number of bytes in each pageparameter BYTE_SIZE    =  8 ;            // Number of bits in a byteparameter ADDR_SIZE     = 8 ;            // number of address bitsparameter ADDR_REG_SIZE = 8 ;            // Size of address register parameter Time_out_for_Write = 40_000;		// Shorten for test//parameter Time_out_for_Write = 10_000_000;		// Scaled to 10 ms.parameter tAA= 550;	  // Worst-case Clock Low to Data Out Valid//***************************************************************************//***************************************************************************//                           Memory Boundaries                             //***************************************************************************//***************************************************************************reg [(ADDR_REG_SIZE - 1):0]  	addr_reg ;    // 8-bit address register.reg [(BYTE_SIZE - 1):0] 	memory[(MEM_SIZE-1):0] ;    //Main Memoryreg [BYTE_SIZE-1: 0] 		S_Byte_Shft_Reg;reg load_address_bit, M_ACK;reg ld_S_Byte_Shft_Reg;reg ld_addr_reg_LSB_byte;reg shift_in;reg shift_out;parameter 			send = 1, receive = 0;parameter 	[31:0]	sending = "send";parameter 	[31:0]	receiving = "recv";reg 		[2:0] 	state_recv, next_state_recv;reg 		[2:0] 	state_send, next_state_send;wire				sda_out;reg 				S_send_rcvb;reg 				Addr_Done;reg S_ACK;//reg Valid_Address_and_A1_flg;reg Valid_Device_Address;//************************************************************************//************************// Slave bus controls  *************************//************************************************************************reg NO_ACK_flag;	// Flag indicating No_ACK from masterreg TOFG;			// Time out flagtri	sda = (S_send_rcvb == send)? ((S_ACK == 0)? sda_out: 1'b0): 1'bz;tri 	sda_in = (S_send_rcvb == receive)? sda : 1'bz;wire	[31:0] receiver = (S_send_rcvb == send)?                sending : ((S_send_rcvb == receive)) ?                  receiving : 32'bx;   event S_START_condition;event S_STOP_condition;event incr_addr_reg;reg S_START, S_STOP;//************************************************************************//********************* S_START and S_STOP conditions ********************//************************************************************************always @ (negedge sda_in) if(scl == 1)begin -> S_START_condition;   $display("************************************** START condition detected");  S_START = 1; S_STOP = 0;  Valid_Device_Address = 0;  @ (posedge scl) S_START = 0; endalways @ (posedge sda_in) if(scl == 1) begin -> S_STOP_condition;S_STOP = 1; Valid_Device_Address = 0;disable MACHINE_LOOP.Main_Loop ; // added by xujun$display ("*************************************** STOP condition detected");end//************************************************************************//************************ Memory Initialization *************************//************************************************************************integer k;initial for (k = 0; k<= MEM_SIZE-1; k = k+1) beginmemory[k] = 8'hFF;end//initial for (k = 0; k<= MEM_SIZE-1; k = k+1) begin    //modified by zxc//memory[k] = k;//endwire [7:0] mem_byte = memory[addr_reg[7:0]]; //@@ Used for debug to watch memory//************************************************************************//*************************** Address Register Controls ******************//************************************************************************always @ (posedge scl)  if (ld_addr_reg_LSB_byte == 1)  //???? addr_reg[ADDR_REG_SIZE-1:0] <= S_Byte_Shft_Reg[7:0]; // else if (ld_addr_reg_LSB_byte == 1) //addr_reg[(ADDR_SIZE-1)/2 -1 : 0] <= S_Byte_Shft_Reg;// Increment after READ  always @ (incr_addr_reg) addr_reg <= addr_reg +1;   //*************************************************************************//**************************     Shift Register    ************************//*************************************************************************assign sda_out = S_Byte_Shft_Reg [BYTE_SIZE-1];always @(posedge scl)if (shift_in == 1)      S_Byte_Shft_Reg <= { S_Byte_Shft_Reg [BYTE_SIZE-2:0], sda_in };else    if (shift_out == 1)       @(negedge scl)         S_Byte_Shft_Reg <= S_Byte_Shft_Reg << 1;   //switching on every positive_edge   else      if (ld_S_Byte_Shft_Reg == 1) S_Byte_Shft_Reg <= memory[addr_reg[7:0]];       //*************************************************************************//*********************** Read/Write State Machine ************************//*************************************************************************always begin : MACHINE_LOOP    Power_up_initialization;    forever begin : Main_Loop      $display("Begin Main Loop");      S_send_rcvb = receive;      $display ("Waiting for START_condition");      @ (S_START_condition)         begin :Data_Transmission           $display("Data_Transmission");           Get_a_Byte;		            Parse_the_Address_Byte_and_Read_or_Write_if_Valid;         end // Data_Transmission    end  // Main_Loop  end  // Machine_Loop //*************************************************************************//*************************************************************************task Get_a_Byte;  begin    NO_ACK_flag = 0;    shift_in = 1;    repeat (8)      begin      @ (posedge scl);       end  endendtasktask Parse_the_Address_Byte_and_Read_or_Write_if_Valid;      begin         @ (negedge scl) shift_in = 0;           NO_ACK_flag = 0;           Check_for_Valid_Device_Address;	      if (Valid_Device_Address)               begin:  Device_Address_Match                  $display ("Device Address Match");                 case (S_Byte_Shft_Reg[0])                     0: Write_or_Dummy_Write_with_Random_Read;                    1: Current_Address_and_Sequential_Read;                       default: $display("Invalid device address word received");                 endcase               end  //Device_Address_Match        endendtasktask Check_for_Valid_Device_Address;     begin        if (S_Byte_Shft_Reg[BYTE_SIZE-1: BYTE_SIZE-7] == Device_Address) Valid_Device_Address = 1;     endendtasktask Write_or_Dummy_Write_with_Random_Read;  begin :Write_Sequence         if (wp == 1)          begin          $display ("Chip is write-protected");          disable Write_Sequence;          end    else begin: Chip_not_write_protected      $display("***************************************** Begin Write Sequence");       Set_Flags_and_Get_Address_Bytes_and_ACK_to_Master;      shift_in = 1; $display("Address bytes are loaded");       @ (posedge scl); 				// MSB is saved        $display("First clock after address bytes are loaded");        @ (posedge S_START or posedge scl)        if (S_START ==1)           begin            $display("Dummywrite detected - this is the device address byte");             Get_a_Byte;            Begin_a_Read_Sequence;           end       else begin: Byte_or_Page_Write         $display("Write sequence");         Get_Remainder_of_Byte;         ACK_and_write_a_Byte;         addr_reg[7:0] <= addr_reg[7:0] +1; $display("Increment the address register");         Execute_page_Write;         $display ("*******************************End of page write");         #Time_out_for_Write TOFG = 0;       end  // Byte_or_Page_Write     end // Chip_not_write_protected  end   // Write_Sequenceendtasktask ACK_and_write_a_Byte;   begin       $display ("ACK and write a byte");      @ (negedge scl) S_ACK = 1; shift_in = 0;      S_send_rcvb = send;      @ (posedge scl) memory[addr_reg[7:0]] <= S_Byte_Shft_Reg[7:0];      @ (negedge scl) S_ACK = 0; shift_in = 1;      S_send_rcvb = receive;   endendtasktask Get_Remainder_of_Byte;  begin    repeat (6)      begin      @ (posedge scl);        end  endendtasktask Set_Flags_and_Get_Address_Bytes_and_ACK_to_Master;    begin               S_send_rcvb = send;      S_ACK = 1; 						// Send ACK to master      @(negedge scl)       S_ACK = 0; shift_in = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -