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

📄 eeprom.txt

📁 用verilog实现了IIC接口与EEPROM存储器的接口设计
💻 TXT
字号:
`timescale 1ns/1ns
`define timeslice 100
module EEPROM(scl,sda);
    input scl;   //串行时钟线
    inout sda;     //串行数据线
    reg out_flag;   //sda数据输出的控制信号
    reg[7:0]   memory[2047:0];
    reg[10:0]   address;
    reg[7:0]   memory_buf;
    reg[7:0]   sda_buf;   //sda数据输出寄存器
    reg[7:0]   shift;      //sda数据输出寄存器
    reg[7:0]   addr_byte;   //EEPROM存储单元地址寄存器
    reg[7:0]   ctrl_byte;   //控制字寄存器
    reg[1:0]   State;      //状态寄存器
    integer i;
   
   //---------------------------------------------
    parameter r7=8'b10101111,w7=8'b10101110,
              r6=8'b10101101,w6=8'b10101100,
              r5=8'b10101011,w5=8'b10101010,
              r4=8'b10101001,w4=8'b10101000,
              r3=8'b10100111,w3=8'b10100110,
              r2=8'b10100101,w2=8'b10100100,
              r1=8'b10100011,w1=8'b10100010,
              r0=8'b10100001,w0=8'b10100000;
   //---------------------------------------------- 
   assign sda=(out_flag==1)?sda_buf[7]:1'bz;
   
   
   //---------寄存器和存储器初始化---------------------
   initial
   begin
       addr_byte=0;
       ctrl_byte=0;
       out_flag=0;
       sda_buf=0;
       State=2'b00;
       memory_buf=0;
       address=0;
       shift=0;
       for(i=0;i<=2047;i=i+1)
          memory[i]=0;
    end
    
   
   //----------启动信号----------------------------
   always@(negedge sda)
      if(scl==1)
         begin
             State=State+1;
             if(State==2'b11)
                disable write_to_eeprom;
            end
   
   //----------主状态机-----------------------------
   always@(posedge sda)
      if(scl==1)   //停止操作
         stop_W_R;
      else
         begin
         casex(State)
            2'b01:
            begin
               read_in;
                  if(ctrl_byte==w7||ctrl_byte==w6||ctrl_byte==w5||ctrl_byte==w4||ctrl_byte==w3||ctrl_byte==w2||ctrl_byte==w1||ctrl_byte==w0)
               begin
                  State=2'b10;
                  write_to_eeprom;   //写操作
              end
                  else
                    State=2'b00;
             end
             2'b11:
             read_from_eeprom;      //读操作
             default:   
                State=2'b00;
        endcase
    end
        
   //-----------操作停止----------------------------
   task stop_W_R;
       begin
           State=2'b00;   //状态返回初始状态
           addr_byte=0;
           ctrl_byte=0;
           out_flag=0;
           sda_buf=0;
       end
   endtask
   
   //--------读进控制字和存储单元地址--------------
   task read_in;
       begin
           shift_in(ctrl_byte);
           shift_in(addr_byte);
       end
   endtask
   
   //-------------EEPROM的写操作---------------------
   task write_to_eeprom;
       begin
           shift_in(memory_buf);
           address={ctrl_byte[3:1],addr_byte};
           memory[address]=memory_buf;
           $display("eeprom---memory[%0h]=%0h",address,memory[address]);
           State=2'b00;   //返回到0状态
       end
   endtask
   
   //-------------EEPROM的读操作---------------------
   task read_from_eeprom;
       begin
           shift_in(ctrl_byte);
           if(ctrl_byte==r7||ctrl_byte==r6||ctrl_byte==r5||ctrl_byte==r4||ctrl_byte==r3||ctrl_byte==r2||ctrl_byte==r1||ctrl_byte==r0)
           begin
               address={ctrl_byte[3:1],addr_byte};
               sda_buf=memory[address];
               State=2'b00;
           end
       end
   endtask
   
   //-------SDA数据线上的数据存入寄存器,数据在SCL的高电平有效--------------------
   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)
           begin
               #`timeslice;
               out_flag=1;    //应答信号输出
               sda_buf=0;
           end
           @(negedge scl)
           #`timeslice out_flag=0;
       end
   endtask
   
   //-------EEPROM存储器中的数据通过SDA数据线输出,数据在SCL低电平时变化-----------
   task shift_out;
       begin
           out_flag=1;
           for(i=6;i>=0;i=i-1)
           begin
               @(negedge scl);
               #`timeslice;
               sda_buf=sda_buf<<1;
           end
           @(negedge scl) #`timeslice sda_buf[7]=1;   //非应答信号输出
           @(negedge scl) #`timeslice out_flag=0;
       end
   endtask
   endmodule

⌨️ 快捷键说明

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