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

📄 eeprm.v

📁 eepromVerilog24c32code并带有文档资料
💻 V
字号:
//***********************************************************************************
//*** eeprm is a verilog HDL behavioral model for AT24C02/4/8/16

`define timeslice2 100 
module eeprm (a0, a1, a2, scl, test, sda) ;

input a0 ;
input a1 ;
input a2 ;
input scl ;
input test ;
inout sda ;

reg[7:0] memory[2047:0],memory_buf,sda_buf;
         //16k bits memory means 2048 bytes
reg[7:0] shift_buf,addr_word,cmm_word;
reg out_flag;
reg[1:0] W_R_state;
integer i;

//----------------------------------------------------------------------------------
parameter r7 = 8'b10101111, w7 = 8'b10101110,     //main7
          r6 = 8'b10101101, w6 = 8'b10101100,     //main6
          r5 = 8'b10101011, w5 = 8'b10101010,     //main5
          r4 = 8'b10101001, w4 = 8'b10101000,     //main4
          r3 = 8'b10100111, w3 = 8'b10100110,     //main3
          r2 = 8'b10100101, w2 = 8'b10100100,     //main2
          r1 = 8'b10100011, w1 = 8'b10100010,     //main1
          r0 = 8'b10100001, w0 = 8'b10100000;     //main0
          
//----------------------------------------------------------------------------------
initial
  begin
    addr_word = 0;
    cmm_word = 0;
    out_flag = 0;
    sda_buf = 0;
    W_R_state = 2'b00;
    memory_buf = 0;
    for (i = 0; i <= 2047; i = i + 1)
      memory[i] = 0;
  end

//----------------------------------------------------------------------------------
assign sda = (out_flag == 1)? sda_buf[7] : 1'bz;
//*** out_flag is used to notify sda is linked to sda_buf
//*** out_flag == 0 means sda_buf is seperated form sda.
//----------------------------------------------------------------------------------


//**********************************************************************************
//**** start receiving
//**********************************************************************************
always @(negedge sda)
   if (scl == 1)
      begin
        W_R_state = W_R_state + 1;
        if (W_R_state == 2'b11)
           begin
             disable work2;
           end
      end

//**********************************************************************************
//**** main state machine
//**********************************************************************************
always @(posedge sda)
  if (scl == 1)
     stop_W_R;
  else
    begin
	  casex(W_R_state)
	    2'b01:
		   begin
		     work1;
			 if (cmm_word == w7 || cmm_word == w6 || cmm_word == w5 || cmm_word == w4 
			     || cmm_word == w3 || cmm_word == w2 || cmm_word == w1 || cmm_word == w0)
				 begin
				   W_R_state = 2'b10;
				   work2;
				 end
			 else
			   W_R_state = 2'b00;
		   end
		2'b11: work3;
		default: W_R_state  = 2'b00;
	  endcase
	end
//*********************************************************************************
//**** stop receiving
//*********************************************************************************
task stop_W_R;
  begin
    W_R_state = 2'b00;
	addr_word = 0;
	cmm_word = 0;
	out_flag = 0;
	sda_buf = 0;
  end
endtask

//*********************************************************************************
//*** Task work1 is used to do the real work of analysis of sda bit stream command,
//*** and according to the command words int bit stream to decide what action it
//*** should take, writing into memory or reading out from memory. Then the real
//*** work of bit by bit storing into memory or bit by bit reading out from memory
//*** begins and continues, according to the command word it received.
//*********************************************************************************

//---------------------------------------------------------------------------------
task work1;
  begin
    shift_in(cmm_word);
	shift_in(addr_word);
  end
endtask

//----------------------------------------------------------------------------------
task work2;
  begin
    shift_in(memory_buf);
	memory[cmm_word[3:1] * 256 + addr_word] = memory_buf;
	W_R_state = 2'b00;
  end
endtask

//-----------------------------------------------------------------------------------
task work3;
  begin
    shift_in(cmm_word);
	if (cmm_word == r7 || cmm_word == r6 || cmm_word == r5  || cmm_word == r4  
	    || cmm_word == r3 || cmm_word == r2 || cmm_word == r1  || cmm_word == r0)
	   begin
	     sda_buf = memory[cmm_word[3:1] * 256 + addr_word];
		 shift_out;
		 W_R_state = 2'b00;
	   end
  end
endtask

//***********************************************************************************
//*** Task shift_in is used to get the sda serial bits into shift[7:0],
//*** one bit every one scl posedge, when serial bits are required to 
//*** be stored into EEPROM.
//***********************************************************************************
task shift_in;
 output[7:0] shift;
  begin
    @(posedge scl) shift[7] = sda;
	@(posedge scl) shift[6] = sda;
	@(posedge scl) shift[5] = sda;
	@(posedge scl) shift[4] = sda;
	@(posedge scl) shift[3] = sda;
	@(posedge scl) shift[2] = sda;
	@(posedge scl) shift[1] = sda;
	@(posedge scl) shift[0] = sda;
	@(negedge scl)  //Send out acknowledge
	  begin
	    #`timeslice2 out_flag = 1;  //link sda_buf to sda ready to send serial data
		sda_buf = 0;                //make sda low to send an acknowledge
	  end
	@(negedge scl)
	   #`timeslice2 out_flag = 0;  //delay half scl2 separate sda_buf with sda
  end
endtask

//***********************************************************************************
//*** Task shift_out is used to send out the byte, sda_buf[7:0] to sda,
//*** one bit every one scl negedge, when the byte stored in memory is
//*** required. out_flag is used to link sda with the MSB of sda_buf[7:0]
//***********************************************************************************
task shift_out;
  begin
    out_flag = 1;
	for (i = 6; i >= 0; i = i - 1)
	  @(negedge scl) #`timeslice2 sda_buf = sda_buf << 1;
	@(negedge scl)
	  #`timeslice2 sda_buf[7] = 1;  //no ack
	@(negedge scl)
	  #`timeslice2 out_flag = 0;  //seprate sda_buf with sda 
  end
endtask
endmodule 

⌨️ 快捷键说明

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