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

📄 i2c.v

📁 at24c0x读写控制模块 支持单字节读写和页读写
💻 V
字号:
////////////////////////////////////////////////////////// File : i2c.v// Author :xinggang xu// Organization:// Created : 11/06/2008      // Last update :      // Platform :        // Simulators :      // Synthesizers:        // Targets :      // Dependency :      /////////////////////////////////////////////////////////      // Description:uart      /////////////////////////////////////////////////////////      // Copyright (C) 2008 xu      ///////////////////////////////////////////////////////////   `timescale 1ns / 10 ps   module i2c( clk,              rst,            sda_in,            sda_out,            en,            scl,               read,            write,            i2c_tbuf,            byte_addr,            i2c_rbuf,               next_wrdata,            read_done            );input clk,rst,read,write;input [7:0]i2c_tbuf,byte_addr;output [7:0]i2c_rbuf;output next_wrdata,read_done;output scl;input sda_in;output sda_out,en;//wire sda;reg en;reg sda_out;reg scl;//reg in;reg [7:0]i2c_tbufs;reg [7:0]i2c_rbuf;reg [1:0]clk_cnt;//????????scl??reg [4:0]bitcnt;//???????????8??wire [4:0]ack_cnt;// reg [4:0]ack_num;        reg [3:0]state;//reg flag_s;parameter tp=1;  assign ack_cnt=ack_num;    parameter  slave_waddr=8'ha0;parameter  slave_raddr=8'ha1;//**************************// state   parameter x_idle=4'b0001;  //????parameter x_start=4'b0010; //?????//parameter repeat_s=4'b0011;parameter r_ack=4'b0100;   //?? ack parameter w_data=4'b0011;  //?????  parameter r_data=4'b0101;  //??????parameter w_ack=4'b0110;   //?? ackparameter x_stop=4'b0111;    //?????//****************************wire wr_byte_addr;wire false_wr;wire rd_data;wire wr_data;wire read_over;    assign wr_byte_addr=(ack_cnt==0  && i2c_tbufs==slave_waddr  && state==r_ack ) ;  //&& (read || write));assign false_wr=(ack_cnt==1 && state==r_ack && read );      assign wr_data=(ack_cnt>=1 && state==r_ack && write);assign rd_data=(ack_cnt>1 && i2c_tbufs==slave_raddr && state==r_ack && read);assign read_over=~read;assign write_over=~write;//assign ack_time=(state==r_ack ||state==w_ack); //assign sda=in? 1'bz:sda;           wire next_wrdata; wire read_done;  assign next_wrdata=(state==w_data && ack_cnt>=2 && write && bitcnt==7 && clk_cnt>=3)      ; assign read_done=(state==w_ack && (clk_cnt==0)); always @(posedge clk or negedge rst)begin    if(~rst)   en<=#tp 0;    else if(state==w_data || state==w_ack || state==x_start || state==x_stop || state==x_idle)  en<=#tp 1;        else en<=#tp 0;end//assign en=(state==w_data || state==w_ack || state==x_start || state==x_stop || state==x_idle);         always @(posedge clk or negedge rst)begin    if(~rst)   state<=#tp x_idle;    else        begin    case(state)        x_idle:if(read || write) state<=#tp x_start;           x_start:if(clk_cnt==3) state<=#tp  w_data;         //repeat_s:if(delay_cnt) state<=#tp  x_start;             r_ack:if(clk_cnt==3)                   begin                  if(wr_data || wr_byte_addr) state<=#tp w_data;                  else if(rd_data) state<=#tp r_data;                     else if(false_wr) state<=#tp x_start;                   else  state<=#tp x_stop;  //write_over                end                          w_data:if(bitcnt>=8 ) state<=#tp r_ack;                    //else if(bitcnt>=16 ) state<=#tp r_ack;                r_data:if(bitcnt>=8 && read_over) state<=#tp x_stop;                else if(bitcnt>=8) state<=#tp w_ack;                w_ack:if(clk_cnt==3) state<=#tp r_data;         x_stop:if (clk_cnt==3)   state<=#tp x_idle;            default:state<=#tp x_idle;    endcase    end  endalways @(posedge clk or negedge rst)begin    if(~rst)    begin	    bitcnt<=#tp 0;	    ack_num<=#tp 0;    end    else    begin      case(state)           x_idle:              begin  	           bitcnt<=#tp 0;	           ack_num<=#tp 0;           end           x_start: begin bitcnt<=#tp 0;  end        w_data:  begin if(clk_cnt==2) bitcnt<=#tp bitcnt+1; end        r_ack:          begin            bitcnt<=#tp 0;              if(clk_cnt==3)               begin                 ack_num<=#tp ack_num+1;              end          end        r_data: begin  if(clk_cnt==2) bitcnt<=#tp bitcnt+1; end        w_ack:          begin             bitcnt<=#tp 0;            if(clk_cnt==3)  ack_num<=#tp ack_num+1;           end        x_stop: begin  bitcnt<=#tp 0;  end        default:;      endcase    end  endalways @(posedge clk or negedge rst)begin  if(~rst)    begin      sda_out<=#tp 1;      i2c_tbufs<=#tp 0;      i2c_rbuf<=#tp 0;         //next_data<=#tp 0;        //read_done<=#tp 0;       // write_done<=#tp 0;     end    else    case(state)          x_idle:          begin            sda_out<=#tp 1;          end        x_start:              begin             if(clk_cnt==2)                   begin                  sda_out<=#tp 0;                  if(write || (read && ack_cnt<2)) i2c_tbufs<=#tp slave_waddr;                  else i2c_tbufs<=#tp slave_raddr;               end          end                  r_ack:          begin              sda_out<=#tp 1;              if(clk_cnt==3)              begin                 if(wr_data )                    begin                  i2c_tbufs<=#tp i2c_tbuf;                 // next_data<=#tp 1;                end                else if (wr_byte_addr) i2c_tbufs<=#tp byte_addr;                else if(rd_data) i2c_tbufs<=#tp slave_raddr;//??????              end          end              w_data:          begin            //next_data<=#tp 0;sim:/i2c_tb/DUT/state            if(clk_cnt==0)                     begin                 sda_out<=#tp i2c_tbufs[7];                i2c_tbufs<=#tp {i2c_tbufs[6:0],i2c_tbufs[7]};                   end          end         r_data:          begin            sda_out<=#tp 1;             if(clk_cnt==2)  i2c_rbuf<=#tp {i2c_rbuf[6:0],sda_in};            end          w_ack:          begin            sda_out<=#tp 0;              end        x_stop:           begin            if(clk_cnt>=2) sda_out<=#tp 1;                  else sda_out<=#tp 0;               end          endcase  endalways @(posedge clk or negedge rst)begin    if(~rst || (~(read || write) && state==x_idle) ) scl<=#tp 1;    else if((read || write) && state==x_idle) scl<=#tp 0;    else if(clk_cnt[0]) scl<=#tp ~scl;endalways @(posedge clk or negedge rst)begin    if(~rst || state==x_idle) clk_cnt<=#tp 0;    else       begin        if(clk_cnt>=3) clk_cnt<=#tp 0;        else clk_cnt<=#tp clk_cnt+1;      endendendmodule   

⌨️ 快捷键说明

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