weiqi7777

FPGA之IIC

0
阅读(4573) 评论(0)

FPGA之IIC

这几天实现FPGA对AT24C02进行读写。采用的是IIC总线,所以要写IIC控制代码。写代码花了一下午,可是调试花了三天。真是相当蛋疼,用了各种方式进行调试。

AT24C02采用的是IIC总线,256KB字节的存储容量。分为32夜,每页有8字节。

首先是写的时序:

clip_image002

如上所示:

第一个是字节写,即每次写一个字节。顺序是首先写器件地址,然后是数据地址,最后是数据。因为IIC可以外挂很多器件,所以需要一个器件地址要表明是对哪一个外设进行操作。

第二个是多字节写,即每次写多个字节。每写一个字节,数据地址会自己加1。比如对数据地址0写数据DATA(n),那么写DATA(n+1)的时候,数据地址会自己加1,即对地址0写数据DATA(N+1)。但是这里要相当注意,这个数据n的个数是有限制的。由每页规定的字节数据个数规定的。AT24C02每页有8字节,所以最高只能写8字节的数据。超过8字节的数据,会覆盖当前页之前的数据。这里要相当注意。

至于这里的回应信号ACK,这里也要注意都是低有效,而且这个ACK信号是AT24C02器件给的。

器件地址,数据手册也有说明:

clip_image004

前4位的值都是1010,后面3位是由你外接的A2,A1,A0电平决定的。后面的R/W是读写位。0表示写,1表示读。

clip_image005

上图是AT24C02的封装图,有三个管脚A2,A1,A0,这里就是器件地址中的A2,A1,A0。这三个可以接不同的电平。所以在一个IIC总线上,最多可以外挂8个AT24C02器件。

然后是读的时序:

clip_image007

读的部分要比写要麻烦很多。下面逐次介绍一下:

第一个图:

读当前数据地址的值。这个当前数据地址是由上次操作的地址决定的。比如,在之前的一次操作,对0x00地址写数据,那么目前的当前数据地址就是0x00。

第二个图:

随机读数据。读取指定的数据地址的值。

第三个图:

读多个数据。读取制定的数据首地址的多个数据的值。这里只要有首地址,每读完一个数据,数据地址会自己加1,这样就可以读取下一个数据。

这里要注意第一个和后面两个在时序上有点不一样。

对于第一个:首先是发器件地址,但是读写位为1。

对于后面两个:也是发器件地址,但是读写位要为0。然后发数据地址。在然后要重新发送起始信号,然后在发器件地址,但是这时候读写位要为1,表示读数据。后面就是读取的数据。如果读的数据不是最后一个,ACK信号为低,如果是最后一个,ACK信号要为高。

这里要注意的地方:

1、随机读数据和连续读数据,第一个发的器件地址的读写位要为0,然后是发数据地址,然后要重新发送起始信号,这个相当重要,不发重新起始信号,是读不到数据的。然后在重新发送器件地址,然后读写位要为1.然后就读数据了。

2、这里的响应信号ACK,要注意这个ACK信号时主机给的,不是AT24C02给的。没有读最后一个数据,主机发ACK低,从机接收到低,表示读数据继续。读最后一个数据,主机发ACK高,从机接收到高,表示数据读取结束。

以上就是读数据要注意的地方,我就是在读数据这里卡了很久,第一个是没有注意,器件地址要发两次,第二个是没有注意要重新发送起始信号,第三个就是ACK信号给错,以为这ACK信号时从机给的。造成数据一直读取不成功。

具体的IIC协议的内容,大家可自行百度查询。

如果注意到了以上的问题,那么写程序控制IIC器件就比较容易了。根据数据手册的时序,注意各个信号之间的时间要求,如保持时间,建立时间要求,然后写程序即可。

采用状态机设计:

首先是定义各个状态:

clip_image009

这里说明一下各个状态作用以及状态中的代码:

这里先说明几个变量的作用:

delay_time_next,delay_time:用来记录每个状态中的计数,该计数是用来使每个状态保持一个固定的时间。

bit_counter_next,bit_counter:用来记录发送8-bit数据的哪一位数据。

counter_number_next, counter_number: 用来记录发送的第几个数据或者是接收的第几个数据。因为考虑到传输多个数据的情况。

i2c_sda_reg: 是FPGA的SDA输出。

i2c_sda: FPGA的SDA输入。 因为SDA是双向的,所以需要将输入和输出分开。向SDA写数据,就向i2c_sda_reg写数据即可。而要读取SDA数据,就只要读取i2c_sda的值即可。

first_byte_to_send:起始信号后发送的第一个字节数据,即器件地址加RW。


第一个idle_state:空闲状态,即没有数据传输时的状态。


idle_state: begin
     delay_time_next  =  'd0;
     bit_counter_next =  'd0;    //send bit counter
     counter_number_next = 'd0;  //send data counter
     read_data_reg  = 'd0;
     write_idle = 1'b1;
     i2c_sda_reg = 1'b1;  //if no data transfer ,i2c data is 1		 
 if(start)
    state_next = ready_state;
 end


在这个状态下,SCL和SDA都为高电平。

第二个ready_state:准备状态,这里其实就是产生开始信号。即SCL保持高,SDA拉低。产生一个开始信号,开始进行IIC通信。


ready_state: begin
    i2c_sda_reg = 1'b0;  //ic2 data pull down.mean begin to transfer data 
 if(delay_time >= 99) //delay 2us, meeting i2c data  setup and hole timing
 begin
    delay_time_next = 'd0;
 state_next = send_device_address_state;
 end
 else
    delay_time_next = delay_time + 1'b1;
 end


第三个状态send_device_address_state:发送器件地址状态,在这个状态中,FPGA将器件地址和RW组成的8-bits数据发送给AT24C02。


//send first byte. including  device address and r/w enable
 send_device_address_state: begin
    if(delay_time == 16) //delay 320ns ,let i2c data meet setup and hold time
     i2c_sda_reg = first_byte_to_send[7-bit_counter];
    if(delay_time >= 199)    //delay 4us , 1-bits data transfer finish
    begin
    if(bit_counter_next >= 7)  //send_8-bits data  finish
   begin
   bit_counter_next = 'd0;
   state_next = wait_device_ack_state;
 delay_time_next = 'd0;
 i2c_sda_reg = 1'b0;
 end
 else
   begin
   bit_counter_next = bit_counter + 1'b1;
 delay_time_next = 'd0;
 end
 end
 else
    delay_time_next = delay_time + 1'b1;
 end


第四个状态wait_device_ack_state:等待响应ACK信号。在发完器件地址8-bits数据后,FPGA要等待从AT24C02发来的响应信号。该响应信号为低,表示通信正常,否则通信不正常。回到idle状态。


//wait ack signal. in this condition ,i2c_sda is input. when i2c_sda is low ,mean receive ack signal success
 wait_device_ack_state: begin     
    if(delay_time >= 199)    //delay 4us
   begin
   if(!i2c_sda)  //receive ack signal
    begin
    state_next       = send_rom_address_state;
 delay_time_next  = 'd0;
 end
 else   //if no receice ack signal , means communication is wrong , back to idle state
    begin
    delay_time_next = 'd0;
 state_next = idle_state;
 end
 end
 else
   delay_time_next = delay_time + 1'b1;
 end


第五个状态,发送数据地址状态:即发送需要操作的地址。


 //send the address will be write or read
 send_rom_address_state: begin
    if(delay_time == 16)     //delay 320ns ,let data meet setup and hold time
     i2c_sda_reg = rom_address[7-bit_counter];
    if(delay_time >= 199)    //delay 4us , 1-bit dats transfer finish
    begin 
    if(bit_counter_next >= 7)  //send_8-bits data finish
   begin
   bit_counter_next = 'd0;
   state_next = wait_address_ack_state;
 delay_time_next = 'd0;
 i2c_sda_reg = 1'b0;
 end
 else
   begin
   bit_counter_next = bit_counter + 1'b1;
 delay_time_next = 'd0;
 end
 end
 else
    delay_time_next = delay_time + 1'b1;
 end


第六个状态,等待数据地址写入回应ACK信号状态:在发完数据地址8-bits数据后,FPGA要等待从AT24C02发来的响应信号。该响应信号为低,表示通信正常,否则通信不正常。回到idle状态。这里要注意了,如果是写数据的话,要跳转到写数据的状态,而如果是读数据的话,要调到重新产生起始信号状态。因为前面说过,读操作的时候,在写完数据地址后,需要重新产生起始信号。


wait_address_ack_state: begin
    i2c_sda_reg = 1'b1;
    if(delay_time >= 199)     //delay 2us
   begin
   if(!i2c_sda)  //receive ack signal
    begin
    //according to the write_or_read  decide enter write state or read state
 //0 mean write state    1 mean read state
    if(!write_or_read)
        state_next       = send_write_data_state;
 else
     state_next		 = regenerate_start_state;
 delay_time_next  = 'd0;
 end
 else   //if no receice ack signal , means communication is wrong , back to idle state
    begin
    delay_time_next = 'd0;
 state_next = idle_state;
 end
 end
 else
   delay_time_next = delay_time + 1'b1;
 end


第七个状态:写数据状态。发送8-bit数据。


send_write_data_state: begin
    if(delay_time == 16)     //delay 320ns ,let data meet hold time
      i2c_sda_reg = rom_write_data[7-bit_counter];
    if(delay_time >= 199)    //delay 4us ,1-bits transfer finish
    begin
    if(bit_counter_next >= 7)  //send_8-bits data finish
   begin
   bit_counter_next = 'd0;
   state_next = wait_write_data_ack_state;
 delay_time_next = 'd0;
 counter_number_next = counter_number + 1'b1; // send 1  8-bits data
 i2c_sda_reg = 1'b0;
 end
 else
   begin
   bit_counter_next = bit_counter + 1'b1;
 delay_time_next = 'd0;
 end
 end
 else
    delay_time_next = delay_time + 1'b1;
 end


第八个状态:等待写数据响应ACK信号:在发完数据8-bits数据后,FPGA要等待从AT24C02发来的响应信号。该响应信号为低,表示通信正常,否则通信不正常。回到idle状态。


wait_write_data_ack_state: begin
    i2c_sda_reg = 1'b0;
    if(delay_time >= 199)     //delay 4us
   begin
   if(!i2c_sda) //receive ack signal
    begin
    //when write operation number == data_number ,means this write operation is finish
 //otherwise continue write operation 
    if( counter_number == write_data_number)
     state_next = stop_state;
 else
     state_next = send_write_data_state;
 delay_time_next  = 'd0;
 write_finish = 1'b1;
 end
 else  //if no receice ack signal , means communication is wrong , back to idle state
    begin
    delay_time_next = 'd0;
 state_next = idle_state;
 end
 end
 else
   delay_time_next = delay_time + 1'b1;
 end 


以上就是写的状态机设计。

之后是读的状态机设计。

第九个状态,重新产生起始信号状态。即重新产生起始信号,SCL保持高电平,SDA先保持高然后在拉低。


 regenerate_start_state: begin
          if(delay_time <= 40)
     i2c_sda_reg = 1'b1;
 else
     i2c_sda_reg = 1'b0;  //ic2 data pull down.mean begin to transfer data 
 if(delay_time >= 99) //delay 2us, meeting i2c data  setup and hole timing
 begin
    delay_time_next = 'd0;
 state_next = rewrite_device_address_state;
 end
 else
    delay_time_next = delay_time + 1'b1;
 end


第十个状态:发送数据地址和读。此时的first_byte_to_send的最低位为1,表示为读数据。


rewrite_device_address_state: begin
    if(delay_time == 16) //delay 320ns ,let i2c data meet setup and hold time
     i2c_sda_reg = first_byte_to_send[7-bit_counter];
    if(delay_time >= 199)    //delay 4us , 1-bits data transfer finish
    begin
    if(bit_counter_next >= 7)  //send_8-bits data  finish
   begin
   bit_counter_next = 'd0;
   state_next = wait_rewrite_ack_state;
 delay_time_next = 'd0;
 i2c_sda_reg = 1'b0;
 end
 else
   begin
   bit_counter_next = bit_counter + 1'b1;
 delay_time_next = 'd0;
 end
 end
 else
    delay_time_next = delay_time + 1'b1;
 end


第十个状态:等待重新写器件地址回应信号。在发完8-bits数据后,FPGA要等待从AT24C02发来的响应信号。该响应信号为低,表示通信正常,否则通信不正常。回到idle状态。


wait_rewrite_ack_state: begin
    i2c_sda_reg = 1'b0;
    if(delay_time >= 199)    //delay 4us
   begin
   if(!i2c_sda)  //receive ack signal
    begin
    state_next       = read_data_state;
 delay_time_next  = 'd0;
 end
 else   //if no receice ack signal , means communication is wrong , back to idle state
    begin
    delay_time_next = 'd0;
 state_next = idle_state;
 end
 end
 else
   delay_time_next = delay_time + 1'b1;
 end


下面才是读数据的状态。

第十一个状态:读数据状态。在SCL高电平读取SDA数据,将数据移位至read_data_reg中保存。这里要注意,有个counter_number_next判断。这个counter_number_next用来表示已经读取的数据个数,因为支持连读,所以当已经读取的个数和设定的个数一致时,就要停止读取。而停止读取和继续读取的响应信号是不一样的。


read_data_state: begin
    if(delay_time == 160)     //delay3.2us ,let data meet setup and hold time			     
  read_data_reg = {read_data[6:0],i2c_sda};
    if(delay_time >= 199)    //delay 4us
    begin
    if(bit_counter_next >= 7)  //read_8-bits data
   begin
   bit_counter_next = 'd0;
 delay_time_next = 'd0;
 counter_number_next = counter_number + 1'b1;
 //if the read data is the last data,goto the no ack state
 //if the read data is not the last data,goto the ack state
 if(counter_number_next == read_data_number )
    state_next = get_read_data_no_ack_state;
 else
    state_next = get_read_data_ack_state;
 end
 else
   begin
   bit_counter_next = bit_counter + 1'b1;
 delay_time_next = 'd0;
 end
 end
 else
    delay_time_next = delay_time + 1'b1;
 end


第十二个状态:发送读取信号响应ACK信号。读取8-bit数据后,如果读取继续,FPGA要向AT24C02发送ACK低电平信号,表示要继续读取数据。


get_read_data_ack_state: begin
    i2c_sda_reg = 1'b0;
    if(delay_time >= 199)     //delay 4us
   begin
//				   if(!i2c_sda) //receive ack signal
//					    begin
////						    when write operation number == data_number ,means this control is finish
////							 otherwise continue write operation 
 state_next = read_data_state;
 delay_time_next  = 'd0;
 read_finish = 1'b1;
//						 end
//					else  //if no receice ack signal , means communication is wrong , back to idle state
//					    begin
//						    delay_time_next = 'd0;
//							 state_next = idle_state;
//						 end
 end
 else
   delay_time_next = delay_time + 1'b1;
 end


第十三个状态:发送读取非响应ACK信号。读到最后一个8-bit数据后,要结束读取,FPGA要向AT24C02发送ACK高电平信号,表示读取结束。


get_read_data_no_ack_state: begin
    i2c_sda_reg = 1'b1;
    if(delay_time >= 199)     //delay 4us
   begin
//				   if(!i2c_sda) //receive ack signal
//					    begin
    //when write operation number == data_number ,means this control is finish
 //otherwise continue write operation 
 state_next = stop_state;
 delay_time_next  = 'd0;
 read_finish = 1'b1;
//						 end
//					else  //if no receice ack signal , means communication is wrong , back to idle state
//					    begin
//						    delay_time_next = 'd0;
//							 state_next = idle_state;
//						 end
 end
 else
   delay_time_next = delay_time + 1'b1;
 end


最后一个状态;发送停止信号状态。SCL保持高电平,SDA数据先保持低,然后在拉高。产生一个结束信号。


 stop_state: begin
    if(delay_time >= 150)
     i2c_sda_reg = 1'b1;
 else
     i2c_sda_reg = 1'b0;
 if(delay_time >= 199)
   state_next = idle_state;
 else
   delay_time_next = delay_time + 1'b1; 
 end


这样,就完成了IIC的状态机设计。这里有几个地方要注意:

1、 读取数据,要重新产生起始信号,如果不重新产生起始信号,读取不到数据。

2、 读取数据的时候,ACK信号是由FPGA给的。这要特别注意,不然的话,状态就直接跳转到idle状态了。既不能读取数据。

因为SDA数据是双向IO口,所以这里要判断SDA什么时候为输入,什么时候为输出。

reg i2c_sda_reg;

assign enable_read = (state == wait_device_ack_state ||state == wait_address_ack_state ||

state == read_data_state ||

//state == wait_read_data_ack_state ||

state == wait_write_data_ack_state ||

state == wait_rewrite_ack_state)?1'b1:1'b0;

assign i2c_sda = enable_read ? 1'bz : i2c_sda_reg_reg;

这里,定义了一个i2c_sda_reg,用来保存SDA的输出值。Enable_read为输入输出判断信号。为1,表示输入,为0,表示输出。那在什么为1,什么时候为0.只需判断现在的状态即可。即在需要从机ACK信号和读取数据是为1.

下面就是SCL。


 always@(*) begin
	    //in idle_state , stop_state and ready_state, I2C clk is 1
	    if(state == idle_state || state == ready_state || state == regenerate_start_state)
		       i2c_scl = 1'b1;
//		 //in ready_state,to meet timing require . I2C clk is 0, wait to transfer data
//       else if(state == ready_state)	
//             i2c_scl = 1'b0;
		 else
          begin
			    //I2C clk period is 4us. so counter value is 200 . set duty is 50% 
             if(delay_time < 100)
				     i2c_scl = 1'b0;
				 else
				     i2c_scl = 1'b1;
			 end
	 end


这里如果不是产生起始信号,空闲状态和重新产生起始信号状态是,前半个状态为0,后半个状态为高。这里要注意,为什么不把停止信号状态放到第一个if中,那是为了防止误产生判断起始信号。

假设在前一个状态,SDA为高,到了停止状态,SCL为高,此时SDA变低,那就误产生了一个起始信号。

而first_byte_to_send,这里代码为:


 reg [7:0] first_byte_to_send;
 always@(*) begin
    //first write device address,the last bit is 0,mean write
    if( state == send_device_address_state ) 
     first_byte_to_send = {4'b1010,device_address,1'b0};
 //when read data ,should rewrite device address, and the last bit is 1,mean read
 else
     first_byte_to_send = {4'b1010,device_address,1'b1};
 end


这里就是确定最低位为低还是高,从而表示还是写还是读。

按照这样一个状态机弄下来,就完成了IIC协议的AT24C02的驱动。然后添加串口模块,将串口发送的数据写入到AT24C02中,然后在将该数据读取回来,看看是否一样。

clip_image011

预先向0x0地址连续写入16个数据。也就是向0x0到0xf 16个地址写入数据。读17个数据,发现前16个数据是一样的,但是最后一个数据是FF。因为这个地址还没有写入数据,所以数据就是0xff。

以下附上的的程序端口部分:


module AT24C02_module(
input clk,
input rst_n,
input start,
input [2:0] device_address, //the device AT24C02 address
input [7:0] rom_address, //the rom address
input [7:0] rom_write_data, //write 8-bits data to the AT24C02
input write_or_read, //write mode or read mode 0 write 1 read
input [7:0] write_data_number, // write data number
input [7:0] read_data_number, //read data number
output reg[7:0] row_read_data, //read 8-bits data from AT24C02 in rom_address
output reg read_finish, //read data finish,mean external can read data
output reg write_finish, //write one byte data finsih.
output reg write_idle, //write data state, 1 mean external can write new data
inout i2c_sda, //I2C data , bidirectional port
output reg i2c_scl, //I2C clk 250K
output enable_read
);


可以看出端口还是比较复杂的,加一些额外信号时为了外部控制方便。

有注释的话,就很容易看出各个端口的作用。

这里最后一个enable_read,这个是为了使用chioscope查看信号而添加的端口。

我在外部有一段代码

assign look_i2c_sda = enable_read==1? i2c_sda:1'b0;

用来查看SDA作为输入时候的值,直接assign look_i2c_sda = i2c_sda。生成bit流会报错,所以这里采用这样的一个方式。


只要注意我说的那些问题,就一定是可以驱动IIC器件的了。。。。


最后贴上整个源代码以及testbench代码:

源代码:


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    21:05:22 11/12/2014 
// Design Name: 
// Module Name:    AT24C02_module 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module AT24C02_module(
			input							clk,
			input							rst_n,
			
			input							start,              
			input		[2:0]				device_address,    //the device AT24C02 address
			input		[7:0]				rom_address,       //the rom address
			input		[7:0] 			rom_write_data,    //write 8-bits data to the AT24C02
			input							write_or_read,		 //write mode or read mode   0 write  1 read
			
			input    [7:0]				write_data_number,       // write data number
			input    [7:0]          read_data_number,  //read  data number
			
			
			output	reg[7:0]       row_read_data,     //read 8-bits data from AT24C02 in rom_address
			
			output	reg				read_finish,       //read data finish,mean external can read data
			output   reg				write_finish,     //write one byte data finsih.
			output   reg				write_idle,       //write data state, 1 mean external can write new data
			
			inout							i2c_sda,            //I2C    data   , bidirectional port
			output	reg				i2c_scl,             //I2C    clk   250K
			
			output						enable_read
    );


    localparam  idle_state    					=    'd0;
	 localparam  ready_state	   				= 	  'd1;
	 localparam  send_device_address_state	   = 	  'd2;
	 localparam  wait_device_ack_state			=    'd3;
	 localparam  send_rom_address_state			=    'd4;
	 localparam  wait_address_ack_state			=    'd5;
	 localparam  send_write_data_state			=    'd6;
	 localparam  wait_write_data_ack_state		=    'd7;
	 localparam  regenerate_start_state       =    'd8;  //regenerate start ,begin to read 
	 localparam  rewrite_device_address_state = 	  'd9;  
	 localparam  wait_rewrite_ack_state			=    'd10;
	 localparam  read_data_state					=	  'd11;
	 localparam  get_read_data_ack_state		=    'd12; 
	 localparam  get_read_data_no_ack_state  = 	  'd13;
	 localparam  stop_state							=    'd14;
	 
	 
	 reg [3:0]  state;       //current state
	 reg [3:0]  state_next;  //next  state
	 always@(posedge clk or negedge rst_n)  begin
	    if(!rst_n)
		     state <= idle_state;
		 else
		     state <= state_next;
	 end
	 
	 
	 //record delay time, because every state has different time.
	 reg [7:0] delay_time;
	 reg [7:0] delay_time_next;
	 always@(posedge clk or negedge rst_n)  begin
	    if(!rst_n)
		     delay_time  <= 'd0;
		 else
		     delay_time  <= delay_time_next;
	 end
	 
	 //record transfer which bit, serial transfer,so need a variable value 
	 reg [2:0] bit_counter;        //current transfer bit
	 reg [2:0] bit_counter_next;   //next transfer bit
	 always@(posedge clk or negedge rst_n)  begin
	    if(!rst_n)
		     bit_counter <= 'd0;
		 else
		     bit_counter <= bit_counter_next;
	 end
	 
	 
	 reg [7:0] first_byte_to_send;
	 always@(*) begin
	    //first write device address,the last bit is 0,mean write
	    if( state == send_device_address_state ) 
		     first_byte_to_send = {4'b1010,device_address,1'b0};
		 //when read data ,should rewrite device address, and the last bit is 1,mean read
		 else
		     first_byte_to_send = {4'b1010,device_address,1'b1};
	 end

	 
	 
	 //when enable_read is 1, i2c_sda is input, otherwise is output
	 //wire enable_read;
	 reg i2c_sda_reg;
	 assign  enable_read = (state == wait_device_ack_state ||state == wait_address_ack_state || 
									state == read_data_state || 
									//state == wait_read_data_ack_state ||
									state == wait_write_data_ack_state ||
									state == wait_rewrite_ack_state)?1'b1:1'b0;
	 assign  i2c_sda  = enable_read ? 1'bz : i2c_sda_reg_reg;
	 
	 
	 reg i2c_sda_reg_reg;
	 always@(posedge clk or negedge rst_n) begin
	    if(!rst_n)
		     i2c_sda_reg_reg = 1'b1;
		 else
		     i2c_sda_reg_reg = i2c_sda_reg;
	 end
	 
	 //write data number or read data number
	 //because write and read can be continuous,so need a counter_number to record the already write or read address number
	 //when counter_number == data_number,that means control finish 
	 reg [7:0] counter_number;
	 reg [7:0] counter_number_next; 
	 always@(posedge clk or negedge rst_n)  begin
	    if(!rst_n)
		    counter_number = 8'd0;
		 else
		    counter_number = counter_number_next;
	 end
	 
	 
	 reg [7:0]  read_data;
	 reg [7:0]  read_data_reg;
	 always@(posedge clk or negedge rst_n) begin
	    if(!rst_n) 
		    read_data <= 8'd0;
		 else
		    read_data <= read_data_reg;
	 end
	 
	 
	 always@(*)  begin
	    state_next	     = state;
		 delay_time_next = delay_time;
		 bit_counter_next = bit_counter;
		 counter_number_next = counter_number;
		 read_data_reg = read_data;
		 i2c_sda_reg = i2c_sda_reg_reg; 
		 read_finish = 1'b0;
		 write_finish = 1'b0;
		 write_idle = 1'b0;
		 case(state)
		 idle_state: begin
		    delay_time_next  =  'd0;
			 bit_counter_next =  'd0;    //send bit counter
			 counter_number_next = 'd0;  //send data counter
			 read_data_reg  = 'd0;
			 write_idle = 1'b1;
			 i2c_sda_reg = 1'b1;  //if no data transfer ,i2c data is 1		 
			 if(start)
			    state_next = ready_state;
		 end
		 ready_state: begin
		    i2c_sda_reg = 1'b0;  //ic2 data pull down.mean begin to transfer data 
			 if(delay_time >= 99) //delay 2us, meeting i2c data  setup and hole timing
				 begin
				    delay_time_next = 'd0;
					 state_next = send_device_address_state;
				 end
			 else
			    delay_time_next = delay_time + 1'b1;
		 end
		 //send first byte. including  device address and r/w enable
		 send_device_address_state: begin
		    if(delay_time == 16) //delay 320ns ,let i2c data meet setup and hold time
			     i2c_sda_reg = first_byte_to_send[7-bit_counter];
		    if(delay_time >= 199)    //delay 4us , 1-bits data transfer finish
			    begin
				    if(bit_counter_next >= 7)  //send_8-bits data  finish
					   begin
						   bit_counter_next = 'd0;
						   state_next = wait_device_ack_state;
							delay_time_next = 'd0;
							i2c_sda_reg = 1'b0;
						end
					 else
					   begin
						   bit_counter_next = bit_counter + 1'b1;
							delay_time_next = 'd0;
						end
				 end
			 else
			    delay_time_next = delay_time + 1'b1;
		 end
		 //wait ack signal. in this condition ,i2c_sda is input. when i2c_sda is low ,mean receive ack signal success
		 wait_device_ack_state: begin     
		    if(delay_time >= 199)    //delay 4us
			   begin
				   if(!i2c_sda)  //receive ack signal
					    begin
						    state_next       = send_rom_address_state;
							 delay_time_next  = 'd0;
						 end
					else   //if no receice ack signal , means communication is wrong , back to idle state
					    begin
						    delay_time_next = 'd0;
							 state_next = idle_state;
						 end
				end
			 else
			   delay_time_next = delay_time + 1'b1;
		 end
		 //send the address will be write or read
		 send_rom_address_state: begin
		    if(delay_time == 16)     //delay 320ns ,let data meet setup and hold time
			     i2c_sda_reg = rom_address[7-bit_counter];
		    if(delay_time >= 199)    //delay 4us , 1-bit dats transfer finish
			    begin 
				    if(bit_counter_next >= 7)  //send_8-bits data finish
					   begin
						   bit_counter_next = 'd0;
						   state_next = wait_address_ack_state;
							delay_time_next = 'd0;
							i2c_sda_reg = 1'b0;
						end
					 else
					   begin
						   bit_counter_next = bit_counter + 1'b1;
							delay_time_next = 'd0;
						end
				 end
			 else
			    delay_time_next = delay_time + 1'b1;
		 end
		 wait_address_ack_state: begin
		    i2c_sda_reg = 1'b1;
		    if(delay_time >= 199)     //delay 2us
			   begin
				   if(!i2c_sda)  //receive ack signal
					    begin
						    //according to the write_or_read  decide enter write state or read state
							 //0 mean write state    1 mean read state
						    if(!write_or_read)
						        state_next       = send_write_data_state;
							 else
							     state_next		 = regenerate_start_state;
							 delay_time_next  = 'd0;
						 end
					else   //if no receice ack signal , means communication is wrong , back to idle state
					    begin
						    delay_time_next = 'd0;
							 state_next = idle_state;
						 end
				end
			 else
			   delay_time_next = delay_time + 1'b1;
		 end
		 send_write_data_state: begin
		    if(delay_time == 16)     //delay 320ns ,let data meet hold time
			      i2c_sda_reg = rom_write_data[7-bit_counter];
		    if(delay_time >= 199)    //delay 4us ,1-bits transfer finish
			    begin
				    if(bit_counter_next >= 7)  //send_8-bits data finish
					   begin
						   bit_counter_next = 'd0;
						   state_next = wait_write_data_ack_state;
							delay_time_next = 'd0;
							counter_number_next = counter_number + 1'b1; // send 1  8-bits data
							i2c_sda_reg = 1'b0;
						end
					 else
					   begin
						   bit_counter_next = bit_counter + 1'b1;
							delay_time_next = 'd0;
						end
				 end
			 else
			    delay_time_next = delay_time + 1'b1;
		 end
		 wait_write_data_ack_state: begin
		    i2c_sda_reg = 1'b0;
		    if(delay_time >= 199)     //delay 4us
			   begin
				   if(!i2c_sda) //receive ack signal
					    begin
						    //when write operation number == data_number ,means this write operation is finish
							 //otherwise continue write operation 
						    if( counter_number == write_data_number)
							     state_next = stop_state;
							 else
							     state_next = send_write_data_state;
							 delay_time_next  = 'd0;
							 write_finish = 1'b1;
						 end
					else  //if no receice ack signal , means communication is wrong , back to idle state
					    begin
						    delay_time_next = 'd0;
							 state_next = idle_state;
						 end
				end
			 else
			   delay_time_next = delay_time + 1'b1;
		 end	
		 regenerate_start_state: begin
          if(delay_time <= 40)
			     i2c_sda_reg = 1'b1;
			 else
			     i2c_sda_reg = 1'b0;  //ic2 data pull down.mean begin to transfer data 
			 if(delay_time >= 99) //delay 2us, meeting i2c data  setup and hole timing
				 begin
				    delay_time_next = 'd0;
					 state_next = rewrite_device_address_state;
				 end
			 else
			    delay_time_next = delay_time + 1'b1;
		 end
		 rewrite_device_address_state: begin
		    if(delay_time == 16) //delay 320ns ,let i2c data meet setup and hold time
			     i2c_sda_reg = first_byte_to_send[7-bit_counter];
		    if(delay_time >= 199)    //delay 4us , 1-bits data transfer finish
			    begin
				    if(bit_counter_next >= 7)  //send_8-bits data  finish
					   begin
						   bit_counter_next = 'd0;
						   state_next = wait_rewrite_ack_state;
							delay_time_next = 'd0;
							i2c_sda_reg = 1'b0;
						end
					 else
					   begin
						   bit_counter_next = bit_counter + 1'b1;
							delay_time_next = 'd0;
						end
				 end
			 else
			    delay_time_next = delay_time + 1'b1;
		 end
		 wait_rewrite_ack_state: begin
		    i2c_sda_reg = 1'b0;
		    if(delay_time >= 199)    //delay 4us
			   begin
				   if(!i2c_sda)  //receive ack signal
					    begin
						    state_next       = read_data_state;
							 delay_time_next  = 'd0;
						 end
					else   //if no receice ack signal , means communication is wrong , back to idle state
					    begin
						    delay_time_next = 'd0;
							 state_next = idle_state;
						 end
				end
			 else
			   delay_time_next = delay_time + 1'b1;
		 end
		 read_data_state: begin
		    if(delay_time == 160)     //delay3.2us ,let data meet setup and hold time			     
				  read_data_reg = {read_data[6:0],i2c_sda};
		    if(delay_time >= 199)    //delay 4us
			    begin
				    if(bit_counter_next >= 7)  //read_8-bits data
					   begin
						   bit_counter_next = 'd0;
							delay_time_next = 'd0;
							counter_number_next = counter_number + 1'b1;
							//if the read data is the last data,goto the no ack state
							//if the read data is not the last data,goto the ack state
							if(counter_number_next == read_data_number )
							    state_next = get_read_data_no_ack_state;
							else
							    state_next = get_read_data_ack_state;
						end
					 else
					   begin
						   bit_counter_next = bit_counter + 1'b1;
							delay_time_next = 'd0;
						end
				 end
			 else
			    delay_time_next = delay_time + 1'b1;
		 end
		 get_read_data_ack_state: begin
		    i2c_sda_reg = 1'b0;
		    if(delay_time >= 199)     //delay 4us
			   begin
//				   if(!i2c_sda) //receive ack signal
//					    begin
////						    when write operation number == data_number ,means this control is finish
////							 otherwise continue write operation 
							 state_next = read_data_state;
							 delay_time_next  = 'd0;
							 read_finish = 1'b1;
//						 end
//					else  //if no receice ack signal , means communication is wrong , back to idle state
//					    begin
//						    delay_time_next = 'd0;
//							 state_next = idle_state;
//						 end
				end
			 else
			   delay_time_next = delay_time + 1'b1;
		 end
		 get_read_data_no_ack_state: begin
		    i2c_sda_reg = 1'b1;
		    if(delay_time >= 199)     //delay 4us
			   begin
//				   if(!i2c_sda) //receive ack signal
//					    begin
						    //when write operation number == data_number ,means this control is finish
							 //otherwise continue write operation	
							 state_next = stop_state;
							 delay_time_next  = 'd0;
							 read_finish = 1'b1;
//						 end
//					else  //if no receice ack signal , means communication is wrong , back to idle state
//					    begin
//						    delay_time_next = 'd0;
//							 state_next = idle_state;
//						 end
				end
			 else
			   delay_time_next = delay_time + 1'b1;
		 end
		 stop_state: begin
		    if(delay_time >= 150)
			     i2c_sda_reg = 1'b1;
			 else
			     i2c_sda_reg = 1'b0;
			 if(delay_time >= 199)
			   state_next = idle_state;
			 else
			   delay_time_next = delay_time + 1'b1; 
		 end
		 default:
		      state_next = idle_state;
		 endcase
	 end
	 
/***********************I2C clk*****************************************/	 
	 always@(*) begin
	    //in idle_state , stop_state and ready_state, I2C clk is 1
	    if(state == idle_state || state == ready_state || state == regenerate_start_state)
		       i2c_scl = 1'b1;
//		 //in ready_state,to meet timing require . I2C clk is 0, wait to transfer data
//       else if(state == ready_state)	
//             i2c_scl = 1'b0;
		 else
          begin
			    //I2C clk period is 4us. so counter value is 200 . set duty is 50% 
             if(delay_time < 100)
				     i2c_scl = 1'b0;
				 else
				     i2c_scl = 1'b1;
			 end
	 end
/***********************I2C clk*****************************************/	


   always@(posedge clk or negedge rst_n) begin
      if(!rst_n)
		    row_read_data <= 8'd0;
		else
		  if(read_finish)
		    row_read_data <= read_data;
	end
	 

endmodule
testbench:



module AT24C02_module_tb;

	// Inputs
	reg clk;
	reg rst_n;
	reg start;
	reg [2:0] device_address;
	reg [7:0] rom_address;
	reg [7:0] rom_write_data;
	reg write_or_read;
	reg [7:0] data_number;

	// Outputs
	wire [7:0] row_read_data;
	wire read_finish;
	wire write_idle;
	wire i2c_scl;

	// Bidirs
	wire i2c_sda;

	// Instantiate the Unit Under Test (UUT)
	AT24C02_module uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.start(start), 
		.device_address(device_address), 
		.rom_address(rom_address), 
		.rom_write_data(rom_write_data), 
		.write_or_read(write_or_read), 
		.data_number(data_number), 
		.row_read_data(row_read_data), 
		.read_finish(read_finish), 
		.write_idle(write_idle), 
		.i2c_sda(i2c_sda), 
		.i2c_scl(i2c_scl)
	);
	
	initial begin
	  clk = 0;
	  forever #10 clk = ~clk;
	end
	
	reg i2c_sda_reg; //SDA input data
	assign i2c_sda = (uut.enable_read == 1)? i2c_sda_reg : 1'bz;  

   reg [7:0]data_reg;

	initial begin
		// Initialize Inputs
		rst_n = 0;
		start = 0;
		device_address = 0;
		rom_address = 0;
		rom_write_data = 0;
		write_or_read = 0; //write
		data_number = 0;
		data_reg = 0;

		// Wait 100 ns for global reset to finish
		#100 rst_n = 1;
		
		//write data
//		repeat(2) begin
//		   data_number = 1;
//			write_or_read = 0; //write
//			write_address_byte(8'h55);
//			rom_write_data = {$random()}%256;	
//			write_data_byte(rom_write_data);
//			#50;		
//		end
//		$stop;
		repeat(3) begin
		  data_number = 1;
		  write_or_read = 1; //read
			data_reg = {$random()}%256;
			write_address_byte(8'h55);
			@(negedge i2c_scl);
			@(negedge i2c_scl);
			read_byte(data_reg);
			#200;
			$stop;
		end
      $stop; 
		// Add stimulus here

	end
	
	task write_address_byte(input [7:0] byte_address); begin
		#20 
		device_address = 3'b000;
		rom_address = byte_address;
		@(posedge clk)  start = 1;
		@(posedge clk)  start = 0;
		wait(uut.state == 'd3)  i2c_sda_reg = 0; //generate device address ack signal
	   wait(uut.state == 'd5)  i2c_sda_reg = 0; //generate rom address ack signal
	end
	endtask
	
	task write_data_byte(input [7	:0] byte_data); begin
	   rom_write_data = byte_data;
		wait(uut.state == 'd7)  i2c_sda_reg = 0; //generate ack signal
		wait(uut.state == 'd0);  
	end
	endtask
	
	task read_byte(input [7:0] byte_data); 
	reg [3:0] i;
	begin
		wait(uut.state == 'd10) i2c_sda_reg = 0;
		@(negedge i2c_scl);
		@(negedge i2c_scl);
		
		for(i=0; i<8; i=i+1) begin
		   i2c_sda_reg = byte_data[7-i];
			@(negedge i2c_scl);
		end
		wait(uut.state == 'd12) i2c_sda_reg = 0;
		wait(uut.state == 'd0);
	end
	endtask
      
endmodule
testbench中用到了task。task在testbench中非常的好用。