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

📄 iiic1.v

📁 实用的I2C程序。This example describes a synthesizable implementation of a I2C.
💻 V
字号:
module IIIC(clk, reset, updata_en, data_rden, scl,  sda,data, reg_readback, base_addr,   updata_req, data_rdreq, sdaout, sda_oe_en,debug1,  debug2, debug3,  debug4 );input clk, reset, updata_en, data_rden, scl,  sda;output[15:0] data;	  output[7:0] base_addr;   input [15:0] reg_readback; output updata_req, data_rdreq, sdaout, sda_oe_en;output  debug1,  debug2, debug3,  debug4 ;//-----------------scl_clr  neg_scl_clr iic_start-------------- reg[7:0]    data0, data1, base_addr; reg pos_scl, pos_sda, pos2_scl, pos2_sda;reg scl_clr,neg_scl_clr,iic_start;wire [15:0] data={data1,data0}	;always@(posedge clk or posedge reset) beginif (reset) beginpos_scl<=0;     pos_sda<=0; pos2_scl<=0;    pos2_sda<=0; scl_clr<=0;    neg_scl_clr<=0; iic_start<=0;    end else begin     	pos_scl<=scl;    	pos2_scl<=pos_scl;    	scl_clr<=~pos2_scl & pos_scl;    	neg_scl_clr<=pos2_scl & ~pos_scl;    pos_sda<=sda;    pos2_sda<=pos_sda;    iic_start<=(pos_scl & pos2_scl) & (~pos_sda & pos2_sda);end end//---------------iic sme--------------parameter          iic_idle	   =	16'b0000_0000_0000_0001;  parameter          iic_bs_addr	=	16'b0000_0000_0000_0010; parameter          iic_bs_addr1	=	16'b0000_0000_0000_0100; parameter          iic_bs_addr2	=	16'b0000_0000_0000_1000; parameter          iic_reg_addr	=	16'b0000_0000_0001_0000; parameter          iic_reg_addr1	=	16'b0000_0000_0010_0000; parameter          iic_reg_addr2	=	16'b0000_0000_0100_0000; parameter          iic_rd_addr	=	16'b0000_0000_1000_0000; parameter          iic_rd_addr1	=	16'b0000_0001_0000_0000; parameter          iic_rd_addr2	=	16'b0000_0010_0000_0000; parameter          iic_wr_dat	   =	16'b0000_0100_0000_0000; parameter          iic_wr_dat1	=	16'b0000_1000_0000_0000; parameter          iic_wr_dat2	=	16'b0001_0000_0000_0000; parameter          iic_rd_dat	   =	16'b0010_0000_0000_0000; parameter          iic_rd_dat1	=	16'b0100_0000_0000_0000; parameter          iic_rd_dat2	=	16'b1000_0000_0000_0000; parameter data_width=3;reg[7:0] addr, buffer, rd_tmp;reg[3:0] bit_count;reg[15:0] iic_seq;reg[3:0] byte_count;reg   byte_end, iic_wr_end, sda_oe, sdaout, idle_ok, rdreg_ack;reg   data_rdreq, updata_req;	wire  debug1=(iic_seq==iic_rd_dat);wire  debug2=(iic_seq==iic_rd_dat2);	//sda_oe;//iic_seq[0];wire  debug3=(iic_seq==iic_rd_dat1);wire  debug4=(iic_seq==iic_idle);wire  sda_oe_en;wave_move  sda_oe_wavemove(	.a(sda_oe), .b(sda_oe_en),.len(8'h0a),	 .clk(clk), .rst(reset));/*always @(posedge clk or posedge reset) beginif  (reset)	beginsda_oe_en<=0; sda_oe_pos<=0;  sda_oe_pos2<=0; end else  begin 	sda_oe_pos<=sda_oe;			sda_oe_pos2<=sda_oe_pos;   sda_oe_en<=sda_oe_pos2;end	 end */always@(posedge clk or posedge reset) beginif (reset) beginaddr<=8'h00; buffer<=8'h00;  idle_ok<=0;bit_count<=4'h0; byte_count<=4'h0;iic_seq<=iic_idle;	 byte_end<=0;  iic_wr_end<=0; sda_oe<=0;	sdaout<=0;	 rdreg_ack<=0;updata_req<=0;  data_rdreq<=0;		rd_tmp<=0;base_addr<=0;	 data0<=0; 				data1<=0; end else begin     byte_end<=(bit_count==4'h8);     if (scl_clr)  bit_count<=bit_count+4'h1; case(iic_seq)iic_idle: begin					iic_wr_end<=0;  	 sda_oe<=0; 	 rdreg_ack<=0;		byte_count<=4'h0;			bit_count<=4'h0;	idle_ok<=1;      if (iic_start)        iic_seq<=iic_bs_addr;        else 			iic_seq<=iic_idle;end    iic_bs_addr: begin      if (scl_clr & (bit_count<8))	   addr[7:0]<={addr[6:0],pos_sda};	casex ({idle_ok, byte_end, (addr==8'haa)})	 		{3'b0??}	: iic_seq<=iic_idle;		{3'b111}	: iic_seq<=iic_bs_addr1;		{3'b110}	: iic_seq<=iic_idle;		{3'b10?}	: iic_seq<=iic_bs_addr;      default  : iic_seq<=iic_idle;		endcase      endiic_bs_addr1:begin       if  (~idle_ok)  iic_seq<=iic_idle;		 else if (neg_scl_clr)begin        sda_oe<=1;  sdaout<=0;        iic_seq<=iic_bs_addr2;       end       else iic_seq<=iic_bs_addr1;endiic_bs_addr2:begin      if (~idle_ok)  iic_seq<=iic_idle;		else if  (neg_scl_clr)begin        iic_seq<=iic_reg_addr;        sda_oe<=0;	        bit_count<=4'h0;       end      else iic_seq<=iic_bs_addr2;     endiic_reg_addr:begin		if  (scl_clr & (bit_count<8) )   buffer[7:0]<={buffer[6:0],pos_sda};              if  (~idle_ok)  iic_seq<=iic_idle;		 else if  (byte_end)         iic_seq<=iic_reg_addr1;       else       iic_seq<=iic_reg_addr;     endiic_reg_addr1:begin       if (~idle_ok)  iic_seq<=iic_idle;		 else if (neg_scl_clr)begin        iic_seq<=iic_reg_addr2;				  sda_oe<=1;  sdaout<=0;       byte_count<=byte_count+4'h1;       end       else iic_seq<=iic_reg_addr1;endiic_reg_addr2:begin       if (~idle_ok)  iic_seq<=iic_idle;		 else if (neg_scl_clr)begin		 sda_oe<=0;        bit_count<=4'h0;  		 iic_seq<=iic_wr_dat; end	        else iic_seq<=iic_reg_addr2;endiic_wr_dat:begin       if (scl_clr & (bit_count<8) )          buffer[7:0]<={buffer[6:0],pos_sda};        /*        if (~idle_ok)  iic_seq<=iic_idle;		 else if (iic_start)  		 begin  iic_seq<=iic_rd_addr;	bit_count<=4'h0; 		 		  rdreg_ack<=1; 	 end		 else if (byte_end)         iic_seq<=iic_wr_dat1;       else       iic_seq<=iic_wr_dat;		  	*/ 	casex ({idle_ok, iic_start, byte_end})	 		{3'b0??}	: iic_seq<=iic_idle;		{3'b11?}	: begin  iic_seq<=iic_rd_addr;	bit_count<=4'h0; 		 						rdreg_ack<=1; 	 end		{3'b101}	: iic_seq<=iic_wr_dat1;		{3'b100}	: iic_seq<=iic_wr_dat;      default  : iic_seq<=iic_idle;		endcase 					    endiic_wr_dat1:begin       if (~idle_ok)  iic_seq<=iic_idle;		 else if (neg_scl_clr)begin        iic_seq<=iic_wr_dat2;				  sda_oe<=1;  sdaout<=0;       byte_count<=byte_count+4'h1;       end       else iic_seq<=iic_wr_dat1;endiic_wr_dat2:begin /*      if (~idle_ok)  iic_seq<=iic_idle;		 else if (neg_scl_clr)begin		 sda_oe<=0;   bit_count<=4'h0;  		 if (byte_count==data_width)  		 begin  iic_seq<=iic_idle; iic_wr_end<=1; end		 else iic_seq<=iic_wr_dat; end		 	        else iic_seq<=iic_wr_dat2;		 */	  	casex ({idle_ok, neg_scl_clr, (byte_count==data_width)})	 		{3'b0??}	: iic_seq<=iic_idle;		{3'b110}	: begin  sda_oe<=0;   bit_count<=4'h0;	iic_seq<=iic_wr_dat; end		{3'b111}	: begin  sda_oe<=0;   bit_count<=4'h0;									iic_seq<=iic_idle; iic_wr_end<=1; end		{3'b10?}	: iic_seq<=iic_wr_dat2;      default  : iic_seq<=iic_idle;		endcase endiic_rd_addr:begin	   rdreg_ack<=0;       if (scl_clr & (bit_count<8))	   addr[7:0]<={addr[6:0],pos_sda};           /*	 if (byte_end) begin                   if (addr==8'hab)         iic_seq<=iic_rd_addr1;                       else     iic_seq<=iic_idle;  end        else       iic_seq<=iic_rd_addr;   */		 casex ({idle_ok, byte_end, (addr==8'hab)})	 		{3'b0??}	: iic_seq<=iic_idle;		{3'b111}	: iic_seq<=iic_rd_addr1;		{3'b110}	: iic_seq<=iic_idle;		{3'b10?}	: iic_seq<=iic_rd_addr;      default  : iic_seq<=iic_idle;		endcase      endiic_rd_addr1:begin       if (~idle_ok)  iic_seq<=iic_idle;		 else if (neg_scl_clr)begin        iic_seq<=iic_rd_addr2;				  sda_oe<=1;   sdaout<=0;	  end       else iic_seq<=iic_rd_addr1;endiic_rd_addr2:begin       if (~idle_ok)  iic_seq<=iic_idle;		 else if (neg_scl_clr)begin	    bit_count<=4'h0;  		 iic_seq<=iic_rd_dat; 		 sdaout<=rd_tmp[7];       rd_tmp[7:0]<={rd_tmp[6:0],1'b0};end	        else iic_seq<=iic_rd_addr2;endiic_rd_dat:begin       if (neg_scl_clr & (bit_count<8) )		begin		    sdaout<=rd_tmp[7];          rd_tmp[7:0]<={rd_tmp[6:0],1'b0};	 end              if (~idle_ok)  iic_seq<=iic_idle;		 else if (byte_end)         iic_seq<=iic_rd_dat1;       else       iic_seq<=iic_rd_dat;endiic_rd_dat1:begin       if (~idle_ok)  iic_seq<=iic_idle;		 else if (neg_scl_clr)begin        iic_seq<=iic_rd_dat2;				  sda_oe<=0;	//att!!! must before the master get control        byte_count<=byte_count+4'h1;       end       else iic_seq<=iic_rd_dat1;endiic_rd_dat2:begin/*        if (~idle_ok)  iic_seq<=iic_idle;		 else if (neg_scl_clr&)begin		 sda_oe<=1;        bit_count<=4'h0; 		 if (byte_count==data_width)  	 iic_seq<=iic_idle;		 else iic_seq<=iic_rd_dat;      end        else iic_seq<=iic_rd_dat2;	 */			  	casex ({idle_ok, neg_scl_clr, (byte_count>2)})	 	  //data_width		{3'b0??}	: iic_seq<=iic_idle;		{3'b110}	: begin  sda_oe<=1;  bit_count<=4'h0;  sdaout<=rd_tmp[7]; 		                  rd_tmp[7:0]<={rd_tmp[6:0],1'b0}; iic_seq<=iic_rd_dat; end		{3'b111}	: begin  sda_oe<=0;   idle_ok<=0;									bit_count<=4'h0; iic_seq<=iic_idle;  end		{3'b10?}	: iic_seq<=iic_rd_dat2;      default  : iic_seq<=iic_idle;		endcase 		enddefault :   begin addr<=8'h00; buffer<=8'h00; bit_count<=4'h0; byte_count<=4'h0;iic_seq<=iic_idle;	sda_oe<=0;	 sdaout<=0;iic_wr_end<=0;  end 					endcase   if (byte_end&scl_clr)begin   case (byte_count)4'h1: begin base_addr<=buffer;  rd_tmp[7:0]<=reg_readback[7:0];	end		//4'h2: begin data0<=buffer;		  rd_tmp[7:0]<=reg_readback[15:8];	end  		//4'h3: data1<=buffer; endcaseend  	if (iic_wr_end) updata_req<=1;			else if (updata_en) updata_req<=0;		if (rdreg_ack)		data_rdreq<=1;	else if  (data_rden)	 data_rdreq<=0;end   end/*always @(posedge clk or posedge reset) beginif  (reset)	begin	end  else  begin end	 end		*/endmodulemodule   wave_move(clk, rst,a, b, len);input clk, rst, a;input [7:0] len;output b;reg a_pos,  a_pos2, a_clr, neg_a_clr, a_counten, neg_a_counten, b;reg  [7:0] a_count, neg_a_count;always @(posedge clk or posedge rst) beginif (rst)	begin a_pos<=0;  a_pos2<=0;  a_clr<=0;  neg_a_clr<=0; b<=0;   a_counten<=0;  a_count<=0; neg_a_counten<=0;  neg_a_count<=0;end else begin  a_pos<=a;  a_pos2<=a_pos;a_clr<=~a_pos2&a_pos;  neg_a_clr<=~a_pos&a_pos2;if (a_clr)  a_counten<=1;  else if (a_count==len)	a_counten<=0; if (a_clr) a_count<=0;else if (a_counten)  a_count<=a_count+8'h01;if (neg_a_clr)  neg_a_counten<=1;  else if (neg_a_count==len)	neg_a_counten<=0; if (neg_a_clr) neg_a_count<=0;else if (neg_a_counten)  neg_a_count<=neg_a_count+8'h01;if (a_count==len)  b<=1;else if (neg_a_count==len)  b<=0;end	 endendmodule

⌨️ 快捷键说明

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