📄 i2c.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 + -