• EEPROM的操作---SPI接口和I2C接口


     

    参考:http://blog.csdn.net/yuanlulu/article/details/6163106

     ROM最初不能编程,出厂什么内容就永远什么内容,不灵活。后来出现了PROM,可以自己写入一次,要是写错了,只能换一片,自认倒霉。人类文明不断进步,终于出现了可多次擦除写入的EPROM,每次擦除要把芯片拿到紫外线上照一下,想一下你往单片机上下了一个程序之后发现有个地方需要加一句话,为此你要把单片机放紫外灯下照半小时,然后才能再下一次,这么折腾一天也改不了几次。历史的车轮不断前进,伟大的EEPROM出现了,拯救了一大批程序员,终于可以随意的修改rom中的内容了

      EEPROM的全称是“电可擦除可编程只读存储器”,即Electrically Erasable Programmable Read-Only Memory。是相对于紫外擦除的rom来讲的。但是今天已经存在多种EEPROM的变种,变成了一类存储器的统称.这种rom的特点是可以随机访问和修改任何一个字节,可以往每个bit中写入0或者1。这是最传统的一种EEPROM,掉电后数据不丢失,可以保存100年,可以擦写100w次。具有较高的可靠性,但是电路复杂/成本也高。因此目前的EEPROM都是几十千字节到几百千字节的,绝少有超过512K的。

      EEPROM的接口分为两种:SPI和I2C。

          SPI接口为四线,型号如AT25XXX。 

        

          I2C接口为2线,型号如24CL02/04/XX.

            

        这两种EEPROM的操作主要按SPI 和I2C的协议操作就可以了,不过也有一些需要注意的地方。在这里记录下来,不涉及细节的处理。

          对于SPI接口的EEPROM:

        1、在写数据的时候需要先写WR_EN的命令,然后在按SPI写写操作。读的时候不需要先写WR_EN.

                     

        2、WR_EN 和WR_DATA 的操作之间要隔一段时间,如10us,不能写完WR_EN就写WR_DATA,否则数据将不能被写入。

             3、WR_DATA操作送入EEPROM之后,要等待一段时间,等EEPROM将数据写入内部,时间长短可以参考datasheet中的一个参数 write_cycle。

           

        4、RD_DATA操作到下一次的WR_EN/WR_DATA命令之间也要间隔一段时间,如400us.

        5、SPI协议的最后一个SPI_CLK也要保证完整,有低有高,不能只有一半,如将SPI_CLK拉高之后不拉低就将SPI_CS信号拉低。

          

         example: verilog 

        EEPROM--SPI interface     

      
    module EE_WR(
    //------------outputs-----------
    output   EE_SI, 
    output   EE_CSb,
    output   EE_SCK, 
    input    EE_SO,
    //------------inputs------------
    input clk,//50MHZ
    input rst
    )/*synthesis noprune*/;
    
     parameter  cmd_wr_en =8'h06         /* synthesis keep */;
     parameter  cmd_wr_sr =16'h0180      /* synthesis keep */; //16'h018C all block are protected
     parameter  cmd_rd_sr =8'h05         /* synthesis keep */;
     parameter  cmd_wr_op =536'h020000_63555560595857565554535251504948474645444342414039383736353433323130292827262524232221201918171615141312111009080706050403020100  /* synthesis keep */;
     //parameter  cmd_wr_op =32'h020000_f5 /* synthesis keep */;
     parameter  cmd_rd_op =24'h030000    /* synthesis keep */;
        
     parameter  tck_delay = 4'd6;
     parameter  num_data_bit = 12'd512;
    
     parameter  IDLE = 5'd0;
     parameter  WR_EN_1 = 5'd1;
     parameter  WR_EN_2 = 5'd2;
     parameter  WR_EN_3 = 5'd3;
     parameter  WR_EN_4 = 5'd4;
     parameter  WR_EN_5 = 5'd5;
    
     parameter  WR_SR_1 = 5'd6;
     parameter  WR_SR_2 = 5'd7;
     parameter  WR_SR_3 = 5'd8;
     parameter  WR_SR_4 = 5'd9;
     parameter  WR_SR_5 = 5'd10; 
     
     parameter  RD_SR_1 = 5'd11;
     parameter  RD_SR_2 = 5'd12;
     parameter  RD_SR_3 = 5'd13;
     parameter  RD_SR_4 = 5'd14;
     parameter  RD_SR_5 = 5'd15;
     parameter  RD_SR_6 = 5'd16;
     parameter  RD_SR_7 = 5'd17; 
     
     parameter  WR_DATA_1 = 5'd18;
     parameter  WR_DATA_2 = 5'd19;
     parameter  WR_DATA_3 = 5'd20;
     parameter  WR_DATA_4 = 5'd21;
     parameter  WR_DATA_5 = 5'd22; 
     
     parameter  RD_DATA_1 = 5'd23;
     parameter  RD_DATA_2 = 5'd24;
     parameter  RD_DATA_3 = 5'd25;
     parameter  RD_DATA_4 = 5'd26;
     parameter  RD_DATA_5 = 5'd27;
     parameter  RD_DATA_6 = 5'd28;
     parameter  RD_DATA_7 = 5'd29; 
     
     
     
    reg   [31:0]   cnt;
    
    always @(posedge clk or negedge rst ) 
     begin
      if(rst == 0 )  cnt <= 0;
      else if(cnt == 32'd500_000_000)   cnt <= 32'd500_000_000;  
      else cnt <= cnt + 1;
     end
     
     wire    wr_en /* synthesis keep */;
     wire    wr_op /* synthesis keep */;
     wire    rd_op /* synthesis keep */;
     wire    rd_sr /* synthesis keep */;
     wire    wr_sr /* synthesis keep */; 
    
      assign  wr_en = (cnt == 32'd000_000_500);  
      assign  rd_sr = (cnt == 32'd000_000_000); 
      assign  wr_sr = (cnt == 32'd000_000_000); 
      assign  wr_op = (cnt == 32'd000_001_000); 
      assign  rd_op = (cnt == 32'd001_000_000);
      
     
     reg   [4:0]   state;
     reg   [3:0]   delay;
     reg   [11:0]  num;
     reg   [7:0]   data_sr;
     reg   [7:0]   data_rd;
     
     reg      spi_clk;
     reg      spi_cs;
     reg      spi_si;  
     
     always @(posedge clk or negedge rst ) 
     begin
      if(rst == 0 )  begin
        spi_clk <= 0;
         spi_cs <= 1;
         spi_si <= 0;
         delay <= 0;
         num <= 0;
         state <= IDLE;
        data_sr    <= 0; 
         data_rd<= 0;
        end
     else begin
       case(state) 
         IDLE : begin
             spi_clk <= 0;
             spi_cs <= 1;
             spi_si <= 0;
             delay <= 0;
             num <= 0;
             data_sr    <= 0; 
             data_rd <= 0;
             
           if(wr_en)  state <= WR_EN_1; 
    //        else if(wr_sr) state <= WR_SR_1; 
    //         else if(rd_sr) state <= RD_SR_1; 
             else if(wr_op) state <= WR_DATA_1; 
             else if(rd_op) state <= RD_DATA_1 ;       
            else  state <= state;
         end
    //-------------wr_en-------------    
       WR_EN_1: begin    //拉低CS
            spi_clk <= 0;
             spi_cs <= 0;
             num <= 7;
            if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1; end
         end      
        WR_EN_2: begin   //sck 下降沿
            spi_clk <= 0;
             spi_si <= cmd_wr_en[num];
             if(delay == tck_delay)  begin  state <= state + 1;  delay <= 0; end             
            else  begin  state <= state;  delay <= delay + 1;   end
         end   
          
          
        WR_EN_3: begin   //sck 上升沿
            spi_clk <= 1;
             spi_si <= spi_si;
            if(delay == tck_delay) begin
                if(num == 0) begin state <= state + 1; delay <= 0;  end
               else begin state <= WR_EN_2; delay <= 0;  num <= num - 1; end    
             end
            else  begin  state <= state;  delay <= delay + 1;  end
         end 
      
       WR_EN_4: begin   //SCK 下降沿延时一个
            spi_clk <= 0;
             spi_si <= spi_si;
             if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;   end
         end    
       WR_EN_5: begin   //CS 拉高
            spi_cs <= 1;
            spi_clk<= 0;
             spi_si <= 0;
             if(delay == tck_delay)  begin state <= IDLE;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;   end
         end   
        
     //-------------wr_sr-------------
      WR_SR_1: begin    //拉低CS
            spi_clk <= 0;
             spi_cs <= 0;
             num <= 15;
             spi_si <= 0;
            if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;  end
         end
      WR_SR_2: begin   //sck 下降沿
            spi_clk <= 0;         
             spi_si <= cmd_wr_sr[num];
             if(delay == tck_delay)  begin state <= state + 1; delay <= 0; end    
            else  begin  state <= state;  delay <= delay + 1;   end
         end             
      WR_SR_3: begin   //sck 上升沿
            spi_clk <= 1;
             spi_si <= spi_si;
            if(delay == tck_delay)  begin 
                if(num == 0) begin  state <= state + 1;  delay <= 0;   end
                 else  begin  state <= WR_SR_2;  delay <= 0; num <= num -1;  end
              end
            else  begin  state <= state;  delay <= delay + 1;  end
         end 
      WR_SR_4: begin   //SCK 下降沿延时一个
            spi_clk <= 0;
             spi_si <= spi_si;
             if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;   end
         end    
      WR_SR_5: begin   //CS 拉高
            spi_cs <= 1;
            spi_clk<= 0;
             spi_si <= 0;
             if(delay == tck_delay)  begin state <= IDLE;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;   end
         end     
     
     //-----rd_sr-----------
       RD_SR_1: begin    //拉低CS
            spi_clk <= 0;
             spi_cs <= 0;
             num <= 7;
             data_sr    <= 0; 
             spi_si <= 0;
            if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <=delay + 1;  end
         end
        RD_SR_2: begin     //sck 下降沿
            spi_clk <= 0;
             spi_si <= cmd_rd_sr[num];
             if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;   end
         end 
       RD_SR_3: begin   //sck 上升沿
            spi_clk <= 1;
             spi_si <= spi_si;
            if(delay == tck_delay)  begin 
                if(num == 0) begin state <= state + 1;  delay <= 0; num <= 7;  end
               else  begin state <= RD_SR_2;  delay <= 0; num <= num - 1;  end
              end         
            else  begin  state <= state;  delay <= delay + 1;  end
         end     
        RD_SR_4: begin    //read SCK 下降沿
            spi_clk <= 0;
             spi_si <= 0;          
             data_sr <= data_sr;
             if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;   end
         end 
        RD_SR_5: begin    //READ sck 上升沿
            spi_clk <= 1;
             data_sr[num]    <= EE_SO;
            if(delay == tck_delay)  begin 
                if(num == 0) begin state <= state + 1;  delay <= 0;  end
               else  begin state <= RD_SR_4;  delay <= 0; num <= num - 1;  end
              end         
            else  begin  state <= state;  delay <= delay + 1;  end
         end     
       RD_SR_6: begin  //SCK 下降沿延时一个
           spi_clk <= 0;
             data_sr <= data_sr;
             if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;   end
         end     
         RD_SR_7: begin  //CS拉高  
             spi_cs <= 1;
             spi_clk<= 0;
              spi_si <= 0;
              if(delay == tck_delay)  begin state <= IDLE;  delay <= 0;  end
             else  begin  state <= state;  delay <= delay + 1;   end
          end     
    
      //---------------------wr_data------------------
       WR_DATA_1: begin    //拉低CS
            spi_clk <= 0;
             spi_cs <= 0;
            spi_si <= 0;
             num <= num_data_bit + 23;
            if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;  end
         end
        WR_DATA_2: begin  //SCK下降沿
            spi_clk <= 0;
             spi_si <= cmd_wr_op[num];
             if(delay == tck_delay)  begin  state <= state + 1;  delay <= 0;   end
            else  begin  state <= state;  delay <= delay + 1;   end
         end 
            
       WR_DATA_3: begin //SCK 上升沿    
            spi_clk <= 1;
             spi_si <= spi_si;
            if(delay == tck_delay)  begin 
               if(num == 0)   begin   state <= state + 1; delay <= 0;  end
               else  begin state <= WR_DATA_2;  delay <= 0;  num <= num - 1; end
                end
            else  begin  state <= state;  delay <= delay + 1;   end
         end 
        WR_DATA_4: begin  //SCK延时下降沿
            spi_clk <= 0;
             spi_si <=  0;
             if(delay == tck_delay)  begin  state <= state + 1;  delay <= 0;   end
            else  begin  state <= state;  delay <= delay + 1;   end
         end  
        WR_DATA_5:  begin  //CS拉高  
             spi_cs <= 1;
             spi_clk<= 0;
              spi_si <= 0;
              if(delay == tck_delay)  begin state <= IDLE;  delay <= 0;  end
             else  begin  state <= state;  delay <= delay + 1;   end
          end 
            
      //---------------------rd_data-------------------
      RD_DATA_1: begin    //拉低CS
            spi_clk <= 0;
             spi_cs <= 0;
            spi_si <= 0;
             num <= 23;
            if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;  end
         end
        RD_DATA_2: begin  //SCK下降沿
            spi_clk <= 0;
             spi_si <= cmd_rd_op[num];
             if(delay == tck_delay)  begin  state <= state + 1;  delay <= 0;   end
            else  begin  state <= state;  delay <= delay + 1;   end
         end          
       RD_DATA_3: begin //SCK 上升沿    
            spi_clk <= 1;
             spi_si <= spi_si;
            if(delay == tck_delay)  begin 
               if(num == 0)   begin   state <= state + 1; delay <= 0;   num <= num_data_bit - 1; end
               else  begin state <= RD_DATA_2;  delay <= 0;  num <= num - 1; end
                end
            else  begin  state <= state;  delay <= delay + 1;   end
         end 
        RD_DATA_4: begin    //read SCK 下降沿
            spi_clk <= 0;
             spi_si <= 0;         
             data_rd <= data_rd;
             if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;   end
         end 
        RD_DATA_5: begin    //READ sck 上升沿
            spi_clk <= 1;
             data_rd[num]    <= EE_SO;
            if(delay == tck_delay)  begin 
                if(num == 0) begin state <= state + 1;  delay <= 0;  end
               else  begin state <= RD_DATA_4;  delay <= 0; num <= num - 1;  end
              end         
            else  begin  state <= state;  delay <= delay + 1;  end
         end     
       RD_DATA_6: begin  //SCK 下降沿延时一个
           spi_clk <= 0;
             data_rd <= data_rd;
             if(delay == tck_delay)  begin state <= state + 1;  delay <= 0;  end
            else  begin  state <= state;  delay <= delay + 1;   end
         end     
        RD_DATA_7 :begin  //CS拉高  
             spi_cs <= 1;
             spi_clk<= 0;
              spi_si <= 0;
              if(delay == tck_delay)  begin state <= IDLE;  delay <= 0;  end
             else  begin  state <= state;  delay <= delay + 1;   end
          end        
       default : state <= 0;
      endcase
     end
    end 
    
    
     assign  EE_CSb = spi_cs;
     assign  EE_SCK = spi_clk;
     assign  EE_SI  = spi_si;
     
    endmodule 
    View Code

       tb: 

      
     `timescale 1 ps/1 ps
      
      module EE_WR_tb ;
       
        wire   EE_SI; 
        wire   EE_CSb;
        wire   EE_SCK; 
        reg    EE_SO;
    
    //------------inputs------------
       reg      clk;//50MHZ
       reg      rst;
      
       
       EE_WR u0_EE_WR(
    //------------outputs-----------
        .EE_SI(EE_SI), 
        .EE_CSb(EE_CSb),
        .EE_SCK(EE_SCK), 
        .EE_SO(EE_SO),
        
    //------------inputs------------
       .clk(clk),//50MHZ
       .rst(rst)
     )/*synthesis noprune*/;
    
    
      parameter T = 20000;
      
      always #(T/2)  clk = ~clk;
      
      initial 
        begin
           clk = 0;
            rst =0;
            
            
            #(300*T)  $stop;
            
            #(200*T)  rst =1; 
            
       end
        
     endmodule 
        
    View Code

     对于I2C的接口:

        1、读写之间按I2C的协议进行就可以。

        2、在读取数据时候,master在接收完8bit数据之后,需要给从机发一个ACK(输出一个SDA =0)。注意读取的时候ACK是由Master发出的,在写数据的时候ACK是由slaver发出的。

       可以参考:http://blog.csdn.net/lingfeng5/article/details/73361833

       3、写数据同样也有一定的write_cycle. 参考datasheet.

         

      example: verilog

      View Code
      
    // `define SIM   //if run modelsim, enable 
     
     module  eeprom_data(
        input            clk,
        input            rst_n,
        
        output                     wr_en,
        output    reg [7:0]   wr_addr,
        output    reg [7:0]   wr_data,
        output    reg           wr_flag,
        
        output                     rd_en,
        output    reg [7:0]    rd_addr,
        input          [7:0]    rd_data,
        output    reg           rd_flag,
        
       input                rd_wrdata_en,    //only one clk cycle high time
        input          wr_rddata_en
        
     
     );
         
        reg  [7:0]  wr_cnt;
        reg  [7:0]  rd_cnt;
     
      
        reg   [31:0]    cnt;
        
        reg    [5:0]        rd_wrdata_en_flag;
      always @(posedge clk or negedge rst_n)
        begin 
             if(rst_n == 0) rd_wrdata_en_flag <= 6'd0;
             else rd_wrdata_en_flag <= {rd_wrdata_en_flag[5:0],rd_wrdata_en};            
        end
                
     
     `ifdef   SIM
        always @(posedge clk or negedge rst_n)
         begin
            if(rst_n == 0) cnt <= 0;
            else if(cnt == 32'd100_000)  cnt <= 0;
            else cnt <= cnt + 1;
         end
         
         
         assign  wr_en = (cnt == 32'd20_000);
         assign  rd_en = (cnt == 32'd70_000);
         
    `else     
         
         
         always @(posedge clk or negedge rst_n)
         begin
            if(rst_n == 0) cnt <= 0;
            else if(cnt == 32'd500_000_000)  cnt <= 0;
            else cnt <= cnt + 1;
         end
     
     
     assign  wr_en = (cnt == 32'd200_000_000);
     assign  rd_en = (cnt == 32'd400_000_000);    
     
     `endif
     
      parameter data_num = 8'd16;  //the data number of need to be write or read 
     //=========================================
     //write
     always @(posedge clk or negedge rst_n)
     begin
        if(rst_n == 0) wr_addr <= 0;
        else if(rd_wrdata_en_flag[5])  begin
            if(wr_addr == data_num) wr_addr <= 0;  
            else wr_addr <= wr_addr + 1;
          end 
        else   wr_addr <= wr_addr;
     end
     
     
     always @(posedge clk or negedge rst_n)
     begin
        if(rst_n == 0) wr_data <= 0;
        else if(rd_wrdata_en_flag[5])  begin
            if(wr_data == data_num) wr_data <= 0;  
            else wr_data <= wr_data + 1;
          end 
        else   wr_data <= wr_data;
     end
         
     
     always @(posedge clk or negedge rst_n)
     begin
        if(rst_n == 0) wr_cnt <= 0;
        else if(rd_wrdata_en_flag[5])  begin
            if(wr_cnt == data_num) wr_cnt <= 0;  
            else wr_cnt <= wr_cnt + 1;
          end 
        else   wr_cnt <= wr_cnt;
     end
     
      
     always @(posedge clk or negedge rst_n)
     begin
        if(rst_n == 0) wr_flag <= 0;
        else if(wr_en) wr_flag <= 1;
        else if(rd_wrdata_en_flag[5])  begin
            if(wr_cnt == data_num) wr_flag <= 0;  
            else wr_flag <= 1;
          end 
        else   wr_flag <= wr_flag;
     end 
     
     
     //====================================
     //read
     
      always @(posedge clk or negedge rst_n)
     begin
        if(rst_n == 0) rd_addr <= 0;
        else if(wr_rddata_en)  begin
            if(rd_addr == data_num) rd_addr <= 0;  
            else rd_addr <= rd_addr + 1;
          end 
        else   rd_addr <= rd_addr;
     end
     
     
    // always @(posedge clk or negedge rst_n)
    // begin
    //    if(rst_n == 0) rd_data <= 0;
    //    else if(wr_rddata_en)  begin
    //        if(rd_data == 8'D127) rd_data <= 0;  
    //        else rd_data <= rd_data + 1;
    //      end 
    //    else   rd_data <= rd_data;
    // end
    //     
     
     
      always @(posedge clk or negedge rst_n)
     begin
        if(rst_n == 0) rd_cnt <= 0;
        else if(wr_rddata_en)  begin
            if(rd_cnt == data_num) rd_cnt <= 0;  
            else rd_cnt <= rd_cnt + 1;
          end 
        else   rd_cnt <= rd_cnt;
     end
         
      always @(posedge clk or negedge rst_n)
     begin
        if(rst_n == 0) rd_flag <= 0;
        else if(rd_en) rd_flag <= 1;
        else if(wr_rddata_en)  begin
            if(data_num == 0)  rd_flag <= 0;
            else if(rd_cnt == (data_num-1)) rd_flag <= 0;  
            else rd_flag <= 1;
          end 
        else   rd_flag <= rd_flag;
     end
     
     wire                fifo_empty;
     wire [4:0]      cnt_fifo;
     wire             clr_fifo;
     
     assign  clr_fifo = wr_rddata_en&&(rd_cnt == (data_num-1));
     
     RD_DATA_BUF u_rd_data_buf(
            .aclr(clr_fifo),
            .clock(clk),
            .data(rd_data),
            .rdreq(1'b0),
            .wrreq(wr_rddata_en),
            .empty(fifo_empty),
            .full(),
            .q(),
            .usedw(cnt_fifo)
            );
     
    
     endmodule 
     
     
    View Code
     //======================================
     //  I2C.v
     //   
     //==========================
    // `define SIM         //if run modelsim, enable 
    
        module I2C( 
      
          input            clk,         //sysclk = 50Mhz
          input            rst_n,
          
          input    [1:0] wr_rd_en,   //wr_rd_en[1] = read, wr_rd_en[0] = write
          input            wr_data_flag, //if still have data to write,the flag always is high
          input            rd_data_flag, //if still have data to read,the flag always is high
          input    [7:0]    wr_addr,
          input    [7:0]    wr_data,
          input    [7:0]    rd_addr,
          
          output    [7:0]    rd_data,
          output            rd_wrdata_en,  //read data from eeprom_data.v to write eeprom
          output         wr_rddata_en,  //write the read data from eeprom to eeprom_data.v
            
          output       ee_I2C_CLK,
          inout        ee_I2C_SDA
       );
          
        reg    [1:0]        wr_rd_en_reg1,wr_rd_en_reg2;
        
       reg        [4:0]   state;
      
        parameter IDLE = 5'd0;
        parameter START_1 = 5'd1;
        parameter START_2 = 5'd2;
        parameter START_3 = 5'd3;
        parameter WR_CTL_1 = 5'd4;
        parameter WR_CTL_2 = 5'd5;
        parameter WR_CTL_ACK1 = 5'd6;
        parameter WR_CTL_ACK2 = 5'd7;
        parameter WR_ADDR_1 = 5'd8;    
        parameter WR_ADDR_2 = 5'd9;    
        parameter WR_ADDR_ACK1 = 5'd10;
        parameter WR_ADDR_ACK2 = 5'd11;
        
        parameter WR_DATA_1 = 5'd12;
        parameter WR_DATA_2 = 5'd13;    
        parameter WR_DATA_3 = 5'd14;    
        parameter WR_DATA_ACK1 = 5'd15;
        parameter WR_DATA_ACK2 = 5'd16;
        
        parameter RD_DATA_1 = 5'd17;
        parameter RD_DATA_2 = 5'd18;    
        parameter RD_DATA_ACK1 = 5'd19;    
        parameter RD_DATA_ACK2 = 5'd20;
        
        parameter STOP_1 = 5'd21;
        parameter STOP_2 = 5'd22;
        parameter STOP_3 = 5'd23;  
        parameter WRITE_TIME = 5'd24;     //delay 10ms   
      
       parameter CMD_control = 7'b1010000; //eeprom addr = 3'b000;
       
    `ifdef SIM
        parameter delay = 20'd100; 
       parameter delay_10ms = 20'd500;
    `else
       parameter delay = 20'd300; 
       parameter delay_10ms = 20'd500000;
    `endif  
        
        always @(posedge clk or negedge rst_n) 
       begin
         if(rst_n == 0) begin 
                wr_rd_en_reg2 <= 2'd0;
                wr_rd_en_reg1 <= 2'd0 ;
            end
         else begin
                wr_rd_en_reg2 <= wr_rd_en_reg1;
                wr_rd_en_reg1 <= wr_rd_en ;
            end
       end
        
        reg     [4:0]   num;  //data = 8bit
        reg     [19:0]  delay_cnt; 
        reg    [7:0]      addr_reg;  //reg addr
        reg     [7:0]    data_reg;  //reg data
        reg                wr_flag;   //write flag
        reg                rd_flag;   //read flag
        reg                rd_restart_flag; // read, the next start flag
        reg                dir_sda_flag;  // dir of sda flag
        reg                rd_wrdata_flag; //when write data ,need read data first
        reg                wr_rddata_flag;
        
        reg    [7:0]   rd_data_reg;
        reg                ee_sclk_reg;   
        reg                ee_data_reg;
      
      always @(posedge clk or negedge rst_n) 
       begin
         if(rst_n == 0) begin  
          state <= IDLE;
            num <= 0;
            delay_cnt <= 0;
            addr_reg <= 0;
            data_reg <= 0;
            wr_flag <= 0;
            dir_sda_flag <= 0;
            rd_flag <= 0;
            rd_restart_flag <= 0;
            rd_wrdata_flag <= 0;
            wr_rddata_flag <= 0;
            rd_data_reg <= 0;
            
            ee_sclk_reg <= 1;
            ee_data_reg <= 1;
            
            end
        else begin
            case(state)
                IDLE: begin
                 num <= 0;
                 delay_cnt <= 0;
                 data_reg  <= 0;
                 addr_reg <= 0;
                 wr_flag <= 0;
                 dir_sda_flag <= 0;
                 rd_flag <= 0;
                 rd_restart_flag <= 0;
                 rd_wrdata_flag <= 0;
                 wr_rddata_flag <= 0;
                 rd_data_reg <= 0;
                 
                 ee_sclk_reg <= 1;
                 ee_data_reg <= 1;
                 
                 if(wr_rd_en_reg2 == 2'b01) begin   //write
                    addr_reg <= wr_addr ;
                    wr_flag <= 1;
                    rd_flag <= 0;
                    state <= START_1;    
                    dir_sda_flag <= 1;                
                 end
                else if(wr_rd_en_reg2 == 2'b10)  begin   //read
                    addr_reg <= rd_addr ;
                    wr_flag <= 0;
                    rd_flag <= 1;
                    state <= START_1;
                    dir_sda_flag <= 1;
                    rd_data_reg <= 0;                
                 end
                else begin
                    state <= state;
                    
                 end
             end
        
        START_1: begin          //reg 
                ee_sclk_reg <= 1;
                ee_data_reg <= 1;
              if(delay_cnt == delay<<1 ) begin
                    state <= state + 1;
                    delay_cnt <= 0;
                 end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                 end
                end
         START_2: begin       //pull down DATA 
                ee_sclk_reg <= 1;
                ee_data_reg <= 0;
              if(delay_cnt == delay ) begin
                    state <= state + 1;
                    delay_cnt <= 0;
                 end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                 end
                end
        START_3: begin         //pull down SCL 
                ee_sclk_reg <= 0;
                ee_data_reg <= 0;
                num <= 7;
              if(delay_cnt == delay ) begin                            
                    delay_cnt <= 0;
                    
                    if(rd_restart_flag) begin 
                            data_reg <= {CMD_control,1'b1};
                            state <= WR_CTL_1;    
                                           
                      end
                    else if((wr_flag ==1)&&(rd_flag == 0)) begin
                            data_reg <= {CMD_control,1'b0};
                            state <= WR_CTL_1;
                        end    
                else if((wr_flag == 0)&&(rd_flag == 1)) begin
                            data_reg <= {CMD_control,1'b0};
                            state <= WR_CTL_1;
                        end         
                    else begin
                            data_reg <= 0;  
                            state <= IDLE;
                        end
                 end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                 end
                end
         WR_CTL_1 : begin   //write CMD,change data at middle of SCL low time
                ee_sclk_reg <= 0;    
                
                if(delay_cnt == delay>>1) ee_data_reg <= data_reg[num];
                else  ee_data_reg <= ee_data_reg;
                
                if(delay_cnt == delay) begin  
                    state <= state + 1;
                    delay_cnt <= 0;
                    end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end
                end
            WR_CTL_2: begin  //write CMD,write data
                ee_sclk_reg <= 1;
                ee_data_reg <= ee_data_reg;
                if(delay_cnt == delay) begin  
                    if(num == 0) begin                     
                        state <= state + 1;
                        delay_cnt <= 0;                         
                      end
                   else begin 
                       state <= WR_CTL_1;
                        delay_cnt <= 0;
                       num <= num -1;
                     end
                  end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end
                end
                
            WR_CTL_ACK1 : begin     //ack
                ee_sclk_reg <= 0;
                ee_data_reg <= 0;
                
                if(delay_cnt == 4)  dir_sda_flag <= 0;  //delay, make sure SDA change in the SCK Low
                else  dir_sda_flag <= dir_sda_flag;
                
                if(delay_cnt == delay) begin
                        state <= state + 1;
                        delay_cnt <= 0;
                      end
                    else  begin
                        state <= state ;
                        delay_cnt <= delay_cnt + 1;
                 end
             end
            WR_CTL_ACK2 : begin
            
                ee_sclk_reg <= 1;
                if(delay_cnt == delay) begin                    
                        delay_cnt <= 0;
                        if(rd_restart_flag)  begin 
                            state <= RD_DATA_1;
                            delay_cnt <= 0;    
                            num <= 7;
                            rd_restart_flag <= 0;
                        end
                        else begin
                           state <= WR_ADDR_1;    
                            num <= 7;
                        end
                      end
                    else  begin
                        state <= state ;
                        delay_cnt <= delay_cnt + 1;
                 end
                    
                end
                
          WR_ADDR_1: begin   //write addr,change data
              ee_sclk_reg <= 0;    
                
                if(delay_cnt == 4)  dir_sda_flag <= 1;
                else  dir_sda_flag <= dir_sda_flag;
        
                if(delay_cnt == delay>>1) ee_data_reg <= addr_reg[num];
                else  ee_data_reg <= ee_data_reg;
                
                if(delay_cnt == delay) begin  
                    state <= state + 1;
                    delay_cnt <= 0;
                    end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end                
                end    
            WR_ADDR_2: begin   //write addr,WRITE data
                ee_sclk_reg <= 1;
                ee_data_reg <= ee_data_reg;
                if(delay_cnt == delay) begin  
                    if(num == 0) begin    
                        state <= WR_ADDR_ACK1;
                        delay_cnt <= 0;    
                     end
                   else begin 
                       state <= WR_ADDR_1;
                        delay_cnt <= 0;
                       num <= num -1;
                     end
                  end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end
                end
            
         WR_ADDR_ACK1 : begin
                ee_sclk_reg <= 0;
                ee_data_reg <= 0;
                
                if(delay_cnt == 4)  dir_sda_flag <= 0;
                else  dir_sda_flag <= dir_sda_flag;
                
                if(delay_cnt == delay) begin
                        state <= state + 1;
                        delay_cnt <= 0;
                      end
                    else  begin
                        state <= state ;
                        delay_cnt <= delay_cnt + 1;
                 end     
           end
       WR_ADDR_ACK2: begin
                ee_sclk_reg <= 1;
                if(delay_cnt == delay) begin
                        delay_cnt <= 0;
                        if((wr_flag ==1)&&(rd_flag == 0))  begin
                            state <= WR_DATA_1 ;
                            num <= 7;
                            end
                        else if((wr_flag ==0)&&(rd_flag == 1))  begin
                            state <= START_1 ;
                            rd_restart_flag <= 1;
                            dir_sda_flag <= 1;
                         end
                        else begin
                            state <= IDLE ;
                        end 
                      end
                    else  begin
                        state <= state ;
                        delay_cnt <= delay_cnt + 1;
                 end     
           end
    
        
            WR_DATA_1 : begin
                ee_sclk_reg <= 0;    
                num <= 7 ;
                
                if(delay_cnt == 3)  dir_sda_flag <= 1;
                else  dir_sda_flag <= dir_sda_flag;
                
                if(delay_cnt == 1) rd_wrdata_flag <= 1;
                else rd_wrdata_flag <= 0;
                
                if(delay_cnt == 5) begin
                    delay_cnt <= 0 ;
                   state <= state + 1;
                    data_reg <= wr_data;
                    
                  end
                else  begin                
                    delay_cnt <= delay_cnt + 1 ;
                   state <= state;
                 end    
            end
            WR_DATA_2 : begin
                ee_sclk_reg <= 0;
                if(delay_cnt == delay>>1) ee_data_reg <= data_reg[num];
                else  ee_data_reg <= ee_data_reg;
                
                if(delay_cnt == delay) begin  
                    state <= state + 1;
                    delay_cnt <= 0;
                    end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end        
              end
              
            WR_DATA_3: begin 
                ee_sclk_reg <= 1;
                ee_data_reg <= ee_data_reg;
                if(delay_cnt == delay) begin  
                    if(num == 0) begin
                            state <= WR_DATA_ACK1;
                            delay_cnt <= 0; 
                            end            
                   else begin 
                       state <= WR_DATA_2;
                        delay_cnt <= 0;
                       num <= num -1;
                     end
                  end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                 end    
             end
               
          WR_DATA_ACK1: begin
               ee_sclk_reg <= 0;
                ee_data_reg <= 0;
                
                if(delay_cnt == 4)  dir_sda_flag <= 0;
                else  dir_sda_flag <= dir_sda_flag;
                
                if(delay_cnt == delay) begin
                        state <= state + 1;
                        delay_cnt <= 0;
                      end
                    else  begin
                        state <= state ;
                        delay_cnt <= delay_cnt + 1;
                 end     
           end
          WR_DATA_ACK2: begin
               ee_sclk_reg <= 1;
                if(delay_cnt == delay) begin
                        delay_cnt <= 0;
                        dir_sda_flag <= 1;
                        
                        if(wr_data_flag)  state <= WR_DATA_1 ;
                        else state <= STOP_1 ;    
                        
                      end
                    else  begin
                        state <= state ;
                        delay_cnt <= delay_cnt + 1;
                 end     
           end    
        
            
        
             
          RD_DATA_1: begin   //read
                 ee_sclk_reg <= 0;
                
                 if(delay_cnt == 4)  dir_sda_flag <= 0;
                 else  dir_sda_flag <= dir_sda_flag;
                
                 if(delay_cnt == delay>>1)     rd_data_reg[num] <= ee_I2C_SDA;
                else  data_reg <= data_reg;
                 
                 if(delay_cnt == delay) begin  
                    state <= state + 1;
                    delay_cnt <= 0;
                    end
                  else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end
             end
          RD_DATA_2: begin
                 ee_sclk_reg <= 1;            
    
                 if(delay_cnt == delay) begin  
                   if(num == 0) begin
                        state <= state + 1;
                        delay_cnt <= 0;
                      end
                     else begin
                       state <= RD_DATA_1;
                        delay_cnt <= 0;
                        num <= num - 1;
                     end
                    end
                  else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end
             end
            RD_DATA_ACK1: begin    //read data  from slave, Notice: the ACK send from Master.    
                ee_sclk_reg <= 0;  
                
                if(delay_cnt == 4)  dir_sda_flag <= 1;
                else  dir_sda_flag <= dir_sda_flag;
                    
                if(rd_data_flag) ee_data_reg <= 0;     //if have data need to read, Master must PULL DOWN the SDA             
                else ee_data_reg <= 1;
                
                if(delay_cnt == delay) begin
                        state <= state + 1;
                        delay_cnt <= 0;
                      end
                    else  begin
                        state <= state ;
                        delay_cnt <= delay_cnt + 1;
                 end     
                    
               end
            RD_DATA_ACK2 : begin 
                
               ee_sclk_reg <= 1;
                if(delay_cnt == 2)  wr_rddata_flag <= 1;
                else wr_rddata_flag <= 0;
                
                if(delay_cnt == delay) begin
                        delay_cnt <= 0;
                                            
                        if(rd_data_flag) begin
                            state <= RD_DATA_1 ;
                            num <= 7;
                         end
                        else begin
                            state <= STOP_1 ;    
                            num <= 0;
                         end
                      end
                    else  begin
                        state <= state ;
                        delay_cnt <= delay_cnt + 1;
                 end      
              end
             
            STOP_1: begin 
                ee_sclk_reg <= 0;    
                ee_data_reg <= 0;
               if(delay_cnt == delay) begin  
                    state <= state + 1;
                    delay_cnt <= 0;
                    end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end                
                end        
            STOP_2: begin
                ee_sclk_reg <= 1;    
                ee_data_reg <= 0;
               if(delay_cnt == delay) begin  
                    state <= state + 1;
                    delay_cnt <= 0;
                    end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end                
                end
            STOP_3: begin
                ee_sclk_reg <= 1;    
                ee_data_reg <= 1;
               if(delay_cnt == delay) begin  
                    if(wr_flag == 1)  begin 
                        state <= state + 1;
                        delay_cnt <= 0;
                        end
                    else begin  //read,not need wait.
                        rd_flag <= 0;
                        state <= IDLE; 
                        delay_cnt <= 0;
                     end
                    end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end                
                end
          WRITE_TIME:  begin  //if write, need wait a lot time to re-satrt.if read, not need wait.
               wr_flag <= 0;
                if(delay_cnt == delay_10ms) begin  
                    state <= IDLE;
                    delay_cnt <= 0;
                    end
                else begin 
                    state <= state ;
                    delay_cnt <= delay_cnt + 1;
                    end                
                end
            default: state <= IDLE;    
         endcase 
        end
      end
     
      
      //----------------------------------
      assign     ee_I2C_CLK = ee_sclk_reg;
      assign     ee_I2C_SDA = dir_sda_flag ? ee_data_reg: 1'bz;
        
      assign     rd_wrdata_en = rd_wrdata_flag;
      assign     wr_rddata_en = wr_rddata_flag;
      
      assign     rd_data = rd_data_reg;
      
       
      endmodule 
      
      
      
      
      
      
      
      
      
    View Code
    // megafunction wizard: %FIFO%
    // GENERATION: STANDARD
    // VERSION: WM1.0
    // MODULE: scfifo 
    
    // ============================================================
    // File Name: RD_DATA_BUF.v
    // Megafunction Name(s):
    //             scfifo
    //
    // Simulation Library Files(s):
    //             altera_mf
    // ============================================================
    // ************************************************************
    // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
    //
    // 16.0.0 Build 211 04/27/2016 SJ Standard Edition
    // ************************************************************
    
    
    //Copyright (C) 1991-2016 Altera Corporation. All rights reserved.
    //Your use of Altera Corporation's design tools, logic functions 
    //and other software and tools, and its AMPP partner logic 
    //functions, and any output files from any of the foregoing 
    //(including device programming or simulation files), and any 
    //associated documentation or information are expressly subject 
    //to the terms and conditions of the Altera Program License 
    //Subscription Agreement, the Altera Quartus Prime License Agreement,
    //the Altera MegaCore Function License Agreement, or other 
    //applicable license agreement, including, without limitation, 
    //that your use is for the sole purpose of programming logic 
    //devices manufactured by Altera and sold by Altera or its 
    //authorized distributors.  Please refer to the applicable 
    //agreement for further details.
    
    
    // synopsys translate_off
    `timescale 1 ps / 1 ps
    // synopsys translate_on
    module RD_DATA_BUF (
        aclr,
        clock,
        data,
        rdreq,
        wrreq,
        empty,
        full,
        q,
        usedw);
    
        input      aclr;
        input      clock;
        input    [7:0]  data;
        input      rdreq;
        input      wrreq;
        output      empty;
        output      full;
        output    [7:0]  q;
        output    [4:0]  usedw;
    
        wire  sub_wire0;
        wire  sub_wire1;
        wire [7:0] sub_wire2;
        wire [4:0] sub_wire3;
        wire  empty = sub_wire0;
        wire  full = sub_wire1;
        wire [7:0] q = sub_wire2[7:0];
        wire [4:0] usedw = sub_wire3[4:0];
    
        scfifo    scfifo_component (
                    .aclr (aclr),
                    .clock (clock),
                    .data (data),
                    .rdreq (rdreq),
                    .wrreq (wrreq),
                    .empty (sub_wire0),
                    .full (sub_wire1),
                    .q (sub_wire2),
                    .usedw (sub_wire3),
                    .almost_empty (),
                    .almost_full (),
                    .eccstatus (),
                    .sclr ());
        defparam
            scfifo_component.add_ram_output_register = "OFF",
            scfifo_component.intended_device_family = "Cyclone IV E",
            scfifo_component.lpm_numwords = 32,
            scfifo_component.lpm_showahead = "OFF",
            scfifo_component.lpm_type = "scfifo",
            scfifo_component.lpm_width = 8,
            scfifo_component.lpm_widthu = 5,
            scfifo_component.overflow_checking = "ON",
            scfifo_component.underflow_checking = "ON",
            scfifo_component.use_eab = "ON";
    
    
    endmodule
    
    // ============================================================
    // CNX file retrieval info
    // ============================================================
    // Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
    // Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
    // Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
    // Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
    // Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "1"
    // Retrieval info: PRIVATE: Clock NUMERIC "0"
    // Retrieval info: PRIVATE: Depth NUMERIC "32"
    // Retrieval info: PRIVATE: Empty NUMERIC "1"
    // Retrieval info: PRIVATE: Full NUMERIC "1"
    // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
    // Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
    // Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1"
    // Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
    // Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
    // Retrieval info: PRIVATE: Optimize NUMERIC "2"
    // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
    // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
    // Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
    // Retrieval info: PRIVATE: UsedW NUMERIC "1"
    // Retrieval info: PRIVATE: Width NUMERIC "8"
    // Retrieval info: PRIVATE: dc_aclr NUMERIC "0"
    // Retrieval info: PRIVATE: diff_widths NUMERIC "0"
    // Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
    // Retrieval info: PRIVATE: output_width NUMERIC "8"
    // Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
    // Retrieval info: PRIVATE: rsFull NUMERIC "0"
    // Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
    // Retrieval info: PRIVATE: sc_aclr NUMERIC "1"
    // Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
    // Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
    // Retrieval info: PRIVATE: wsFull NUMERIC "1"
    // Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
    // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
    // Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"
    // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
    // Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "32"
    // Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF"
    // Retrieval info: CONSTANT: LPM_TYPE STRING "scfifo"
    // Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8"
    // Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "5"
    // Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
    // Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
    // Retrieval info: CONSTANT: USE_EAB STRING "ON"
    // Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT NODEFVAL "aclr"
    // Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
    // Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
    // Retrieval info: USED_PORT: empty 0 0 0 0 OUTPUT NODEFVAL "empty"
    // Retrieval info: USED_PORT: full 0 0 0 0 OUTPUT NODEFVAL "full"
    // Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
    // Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
    // Retrieval info: USED_PORT: usedw 0 0 5 0 OUTPUT NODEFVAL "usedw[4..0]"
    // Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
    // Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
    // Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
    // Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0
    // Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
    // Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
    // Retrieval info: CONNECT: empty 0 0 0 0 @empty 0 0 0 0
    // Retrieval info: CONNECT: full 0 0 0 0 @full 0 0 0 0
    // Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0
    // Retrieval info: CONNECT: usedw 0 0 5 0 @usedw 0 0 5 0
    // Retrieval info: GEN_FILE: TYPE_NORMAL RD_DATA_BUF.v TRUE
    // Retrieval info: GEN_FILE: TYPE_NORMAL RD_DATA_BUF.inc FALSE
    // Retrieval info: GEN_FILE: TYPE_NORMAL RD_DATA_BUF.cmp FALSE
    // Retrieval info: GEN_FILE: TYPE_NORMAL RD_DATA_BUF.bsf FALSE
    // Retrieval info: GEN_FILE: TYPE_NORMAL RD_DATA_BUF_inst.v FALSE
    // Retrieval info: GEN_FILE: TYPE_NORMAL RD_DATA_BUF_bb.v TRUE
    // Retrieval info: LIB_FILE: altera_mf
    View Code
    TB:
    `timescale 1 ps/1 ps
    
      module  EEPROM_TB;
      reg            clk;
      reg            rst_n;
      
      wire       ee_I2C_CLK;
      wire       ee_I2C_SDA;
    
        
        EEPROM u_EEPROM(
            .clk(clk),
            .rst_n(rst_n),
            
            .EEPROM_SCK(ee_I2C_CLK),
            .EEPROM_SDA(ee_I2C_SDA)
         
         );
    
        parameter T = 20000;
        
        always #(T/2)  clk = ~clk;
         
        initial 
         begin
            clk = 0;
            rst_n = 0;
            
            $stop;
    
            #(500*T)  rst_n = 1; 
        end
        
     endmodule 
    
    
        
        
        
        
    View Code

        

         

  • 相关阅读:
    Elixir 简介
    docker 基础
    函数式和面向对象
    react-native 简介及环境
    Ecto 总结
    使用 dep 配置 golang 开发环境
    docker 私有仓库简易搭建
    Elixir 单元测试
    基于资源的权限系统-API设计
    差商代微商的方法求解一阶常微分方程
  • 原文地址:https://www.cnblogs.com/fhyfhy/p/7878679.html
Copyright © 2020-2023  润新知