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

📄 eeprom_wr.v

📁 I2C通信的程序
💻 V
字号:
`timescale 1ns/1ns module EEPROM_WR(SDA,SCL,RESET,CLK,nrw,cs,ADDR,DATA,link_sda,link_read); output SCL; //串行时钟线 input RESET; //复位信号 input CLK; //时钟信号输入 //input WR,RD; //读写信号 input nrw;input cs;input[6:0] ADDR; //地址线 inout SDA; //串行数据线 inout[7:0] DATA; //并行数据线 output link_sda;output link_read;reg Ack_bit; reg SCL; reg WF,RF; //读写操作标志 reg FF; //标志寄存器 reg [1:0] head_buf; //启动信号寄存器 reg [1:0] stop_buf; //停止信号寄存器 reg [7:0] sh8out_buf; //EEPROM写寄存器 reg [8:0] sh8out_state; //EEPROM 写状态寄存器 reg [9:0] sh8in_state; //EEPROM 读状态寄存器 reg [2:0] head_state; //启动状态寄存器 reg [2:0] stop_state; //停止状态寄存器 reg [10:0] main_state; //主状态寄存器 reg [7:0] data_from_rm; //EEPROM读寄存器 reg link_sda; //SDA 数据输入EEPROM开关 reg link_read; //EEPROM读操作开关 reg link_head; //启动信号开关 reg link_write; //EEPROM写操作开关 reg link_stop; //停止信号开关 reg link_idle;reg link_error;wire sda0,sda1,sda2,sda3,sda4;//--------------串行数据在开关的控制下有次序的输出或输入------------------- assign sda1 = (link_head) ? head_buf[1] : 1'b0; assign sda2 = (link_write) ? sh8out_buf[7] : 1'b0; assign sda3 = (link_stop) ? stop_buf[1] : 1'b0;assign sda0 = (link_idle) ? 1'b1 : 1'b0; assign sda4 = (sda1 | sda2 | sda3 | sda0); assign SDA = (link_sda) ? sda4 : 1'bz; assign DATA = (link_read) ? data_from_rm : 8'hzz; //--------------------------------主状态机状态------------------------------------------ parameter Idle = 11'b00000000001,           Ready = 11'b00000000010,           Write_start = 11'b00000000100,           Addr_write = 11'b00000001000, 		    Ack_write = 11'b00000010000, 		    Data_write = 11'b00000100000, 		    Ack_address = 11'b00001000000, 		    error = 11'b00010000000, 		    Data_read = 11'b00100000000, 		    Stop = 11'b01000000000, 		    Ack_read = 11'b10000000000, //-------------------------并行数据串行输出状态-----------------------------         sh8out_bit7 = 9'b000000001, 		  sh8out_bit6 = 9'b000000010, 		  sh8out_bit5 = 9'b000000100, 		  sh8out_bit4 = 9'b000001000, 		  sh8out_bit3 = 9'b000010000, 		  sh8out_bit2 = 9'b000100000, 		  sh8out_bit1 = 9'b001000000, 		  sh8out_bit0 = 9'b010000000, 		  sh8out_end = 9'b100000000; //--------------------------串行数据并行输出状态---------------------------- parameter sh8in_begin = 10'b0000000001, 		    sh8in_bit7 = 10'b0000000010, 		    sh8in_bit6 = 10'b0000000100, 		    sh8in_bit5 = 10'b0000001000, 		    sh8in_bit4 = 10'b0000010000, 		    sh8in_bit3 = 10'b0000100000, 		    sh8in_bit2 = 10'b0001000000, 		    sh8in_bit1 = 10'b0010000000, 		    sh8in_bit0 = 10'b0100000000, 		    sh8in_end = 10'b1000000000, //---------------------------------启动状态---------------------------------- 		  head_begin = 3'b001, 		  head_bit = 3'b010, 		  head_end = 3'b100, //---------------------------------停止状态---------------------------------- 		  stop_begin = 3'b001, 		  stop_bit = 3'b010, 		  stop_end = 3'b100; parameter YES = 1,		  NO = 0; //-------------产生串行时钟,为输入时钟的二分频------------------- always @(negedge CLK) if(RESET) SCL <= 0; else SCL <= ~SCL; //-----------------------------主状态程序---------------------------------- always @ (posedge CLK) 	if(RESET) 	begin 		link_read <= NO; 		link_write <= NO; 		link_head <= NO; 		link_stop <= NO; 		link_sda <= NO; 		link_idle <= NO;		link_error <= NO;		RF <= 0; 		WF <= 0; 		FF <= 0; 		main_state <= Idle; 	end 	else 	begin 		casex(main_state) 		Idle: begin 			link_read <= NO; 			link_write <= NO; 			link_head <= NO; 			link_stop <= NO; 			link_sda <= YES;			link_idle <= YES;			link_error <= NO; 			if(~cs) begin 			  if(nrw) begin				WF <= 1; 				main_state <= Ready ; 				end 			else  begin 				RF <= 1; 				main_state <= Ready ; 				end 			end			else begin 				WF <= 0; 				RF <= 0; 				main_state <= Idle; 				end 			end 		Ready: begin 			link_read <= NO;			link_write <= NO; 			link_stop <= NO; 			link_head <= YES; 			link_sda <= YES;			link_idle <= NO; 			head_buf[1:0] <= 2'b10; 			stop_buf[1:0] <= 2'b01; 			head_state <= head_begin; 			FF <= 0; 			main_state <= Write_start; 			end 		Write_start: 			if(FF == 0) 				shift_head; 			else begin				link_head <= NO;  				FF <= 0; 				main_state <= Addr_write;				link_sda <= YES; 				link_write <= YES; 				sh8out_state <= sh8out_bit6;				if(WF) 				sh8out_buf[7:0] <= {ADDR[6:0],1'b0}; 				else if(RF)				sh8out_buf[7:0] <= {ADDR[6:0],1'b1}; 			end 		Addr_write: 			if(FF == 0) 				shift8_out; 			else begin 				FF <= 0;								link_sda <= NO; 				link_write <= NO; 				main_state <= Ack_address;				end 		Ack_address: 		     if(SCL && SDA==0) begin		        if(WF) begin		            main_state <= Data_write;		            sh8out_buf[7:0] <= DATA;				      sh8out_state <= sh8out_bit7;		        end		        else if(RF) begin				link_sda <= NO; 				link_write <= NO; 				FF <= 0; 				sh8in_state <= sh8in_begin; 				main_state <= Data_read; 		        end		      end		      else if(SCL && SDA==1) begin		          main_state <= Stop;		          stop_state <= stop_begin;		          link_error <= YES;		          end		        		Data_write: 			if(FF == 0) 				shift8_out; 			else begin  				main_state <= Ack_read; 				link_write <= NO;				link_sda <= NO; 				FF <= 0; 				end 		Data_read: 			if(FF == 0) 				shift8in; 			else begin 				FF <= 0; 				main_state <= Ack_write; 				link_sda <= YES;  				end 	   Ack_write: 	       if(!SCL) begin				link_stop <= YES; 				link_sda <= YES; 				link_read <= YES;				stop_state <= stop_bit; 	//			FF <= 0; 				main_state <= Stop;		          end   		Ack_read: 		     if(SCL && SDA==0) begin		          main_state <= Stop;		          stop_state <= stop_begin; 		          end		     else if(SCL && SDA==1) begin		          main_state <= Stop;		          stop_state <= stop_begin;		          link_error <= YES;		          end	          						Stop: 			if(FF == 0) 				shift_stop; 			else begin            				FF <= 0; 				main_state <= Idle; 				end 		default: 			main_state <= Idle; 		endcase 	end //------------------------串行数据转换为并行数据任务---------------------------------- task shift8in; 	begin 	casex(sh8in_state) 		sh8in_begin: 			sh8in_state <= sh8in_bit7; 			sh8in_bit7: 			if(SCL) 				begin 				data_from_rm[7] <= SDA; 				sh8in_state <= sh8in_bit6; 				end 			else 				sh8in_state <= sh8in_bit7; 		sh8in_bit6: 			if(SCL) 				begin 				data_from_rm[6] <= SDA; 				sh8in_state <= sh8in_bit5; 				end 			else 				sh8in_state <= sh8in_bit6; 		sh8in_bit5: 			if(SCL) 				begin 				data_from_rm[5] <= SDA; 				sh8in_state <= sh8in_bit4;				end 			else 				sh8in_state <= sh8in_bit5; 		sh8in_bit4: 			if(SCL) 				begin 				data_from_rm[4] <= SDA; 				sh8in_state <= sh8in_bit3; 				end 			else 				sh8in_state <= sh8in_bit4; 		sh8in_bit3: 			if(SCL) 				begin 				data_from_rm[3] <= SDA; 				sh8in_state <= sh8in_bit2; 				end			else 				sh8in_state <= sh8in_bit3; 		sh8in_bit2: 			if(SCL) 				begin 				data_from_rm[2] <= SDA; 				sh8in_state <= sh8in_bit1; 				end 			else 				sh8in_state <= sh8in_bit2; 		sh8in_bit1: 			if(SCL) 				begin 				data_from_rm[1] <= SDA; 				sh8in_state <= sh8in_bit0; 				end 			else 				sh8in_state <= sh8in_bit1; 		sh8in_bit0: 			if(SCL) 				begin 				data_from_rm[0] <= SDA; 				sh8in_state <= sh8in_bit7;				FF <= 1;  				end 			else 				sh8in_state <= sh8in_bit0; 		default: 			begin 				link_read <= NO; 				sh8in_state <= sh8in_bit7; 				end 		endcase 	end endtask //------------------------------ 并行数据转换为串行数据任务 --------------------------- task shift8_out; 	begin 	casex(sh8out_state) 		sh8out_bit7: 			if(!SCL) 				begin 				link_sda <= YES; 				link_write <= YES; 				sh8out_state <= sh8out_bit6; 				end 			else 				sh8out_state <= sh8out_bit7; 		sh8out_bit6: 			if(!SCL) 				begin 				link_sda <= YES; 				link_write <= YES; 				sh8out_state <= sh8out_bit5; 				sh8out_buf <= sh8out_buf<<1; 				end 			else 				sh8out_state <= sh8out_bit6; 		sh8out_bit5: 			if(!SCL) 				begin 				sh8out_state <= sh8out_bit4; 				sh8out_buf <= sh8out_buf<<1; 				end 			else 				sh8out_state <= sh8out_bit5; 		sh8out_bit4: 			if(!SCL) 				begin 				sh8out_state <= sh8out_bit3; 				sh8out_buf <= sh8out_buf<<1; 				end 			else 				sh8out_state <= sh8out_bit4; 		sh8out_bit3: 			if(!SCL) 				begin 				sh8out_state <= sh8out_bit2; 				sh8out_buf <= sh8out_buf<<1; 				end 			else 				sh8out_state <= sh8out_bit3; 		sh8out_bit2: 			if(!SCL) 				begin 				sh8out_state <= sh8out_bit1; 				sh8out_buf <= sh8out_buf<<1; 				end 			else 				sh8out_state <= sh8out_bit2; 		sh8out_bit1: 			if(!SCL) 				begin 				sh8out_state <= sh8out_bit0; 				sh8out_buf <= sh8out_buf<<1; 				end 			else 				sh8out_state <= sh8out_bit1; 		sh8out_bit0:			if(!SCL) 				begin 				sh8out_state <= sh8out_end; 				sh8out_buf <= sh8out_buf<<1; 				end 			else 				sh8out_state <= sh8out_bit0; 		sh8out_end: 			if(SCL) 				begin  				FF <= 1; 				end 		endcase 	end endtask //--------------------------- 输出启动信号任务 --------------------------------- task shift_head; 	begin 	casex(head_state) 		head_begin: 			if(!SCL) 				begin 				link_write <= NO; 				link_sda <= YES; 				link_head <= YES; 				head_state <= head_bit; 				end 			else 				head_state <= head_begin; 		head_bit: 			if(SCL) 				begin 				FF <= 1; 				head_buf <= head_buf<<1; 				head_state <= head_end; 				end 			else 				head_state <= head_bit; 		head_end: 			if(!SCL) 				begin 				link_head <= NO; 				link_write <= YES;				 				end 			else 				head_state <= head_end; 		endcase 	endendtask //--------------------------- 输出停止信号任务 -------------------------------------- task shift_stop; 	begin 	casex(stop_state) 		stop_begin: 			if(!SCL) 				begin 				link_sda <= YES; 				link_write <= NO; 				link_stop <= YES; 				stop_state <= stop_bit; 				end 			else 				stop_state <= stop_begin; 		stop_bit: 			if(SCL) 				begin 				stop_buf <= stop_buf<<1; 				stop_state <= stop_end; 				end 			else 				stop_state<= stop_bit; 		stop_end: 			if(!SCL) 				begin 				link_head <= NO; 				link_stop <= NO; 				link_sda <= YES;				link_idle <= YES;				link_read <= NO;				link_error <= NO; 				FF <= 1; 				end 			else 				stop_state <= stop_end; 			endcase 		end 	endtask endmodule

⌨️ 快捷键说明

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