Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

I2C_master

.txt
Скачиваний:
10
Добавлен:
26.06.2022
Размер:
3.56 Кб
Скачать
`timescale 1ns / 100ps

module I2C_master
(
	input slave,
	input start,
	input stop,
	input clk,
	inout sda,
	input [6:0] addr,
	input [7:0] data,
	input cmd,
	output reg wd,
	output reg rd,
	output reg we, //slave or master
	output reg scl
);

integer latch; //между sda и scl начало/конец
integer sda_c; 
integer data_c; 
integer addr_c;
integer counter; //изменение в нулевом состоянии

reg [3:0] state;
	
parameter WAITING = 0,
				BEGINNING = 1,
				ADDRESS = 2,
				RW_CMD = 3,
				WR_ACK = 4,
				RD_ACK = 5,
				WR_DATA = 6,
				RD_DATA = 7,
				SEND_ACK = 8,
				ENDING = 9;
initial state <= WAITING;
assign sda = we ? wd : 1'bz;

always@ (posedge clk)
begin
	case (state)
	WAITING:
	begin
		scl <= 1'b1;
		we <= 1'b1;
		wd <= 1'bz;
		latch = 0;
		sda_c = 3;
		data_c = 7;
		addr_c = 6;
		counter = 0;
		
		if (start) state <= BEGINNING;
	end
	
	BEGINNING:
	begin
		if (counter == 2)
		begin
		scl <=!scl;
		counter =0;
		end
			counter = counter +1;
		
		if (latch == 1)
		begin
		wd <= 1'b0;
		state <= ADDRESS;
		end
			latch <= latch +1;
	end
	
	ADDRESS:
	begin
		if (counter == 2)
		begin
		scl <=!scl;
		counter =0;
		end
			counter = counter +1;
			
		if (sda_c == 4)
		begin
		wd <= addr[addr_c];
		sda_c = 0;
			if (addr_c == 3'd0) state <= RW_CMD;
		addr_c = addr_c - 1;
		end
			sda_c = sda_c + 1;
		
	end
	
	RW_CMD:
	begin
		if (counter == 2)
		begin
		scl <=!scl;
		counter =0;
		end
			counter = counter +1;
			
		if (sda_c == 4)
		begin
		wd <= cmd;
		sda_c = 0;
		state <= cmd ? RD_ACK : WR_ACK;
		end
			sda_c = sda_c + 1;
	end
	
	WR_ACK:
	begin
		if (counter == 2)
		begin
		scl <=!scl;
		counter =0;
		end
			counter = counter +1;
		
		if (sda_c == 4)
		begin
		we <= 1'b0;
		rd <= we ? 1'b0 : sda;
		sda_c = 0;
		data_c <= 4'd7;
		state <= stop ? ENDING : WR_DATA;
		end
			sda_c = sda_c + 1;
	end
	
	RD_ACK:
	begin
		if (counter == 2)
		begin
		scl <=!scl;
		counter =0;
		end
			counter = counter +1;
		
		if (sda_c == 4)
		begin
		we <= 1'b0;
		rd <= we ? 1'b0 : sda;
		sda_c = 0;
		data_c <= 4'd7;
		state <= RD_DATA;
		end
			sda_c = sda_c + 1;
	end
	
	WR_DATA:
	begin
		if (counter == 2)
		begin
		scl <=!scl;
		counter =0;
		end
			counter = counter +1;
		
		if (sda_c == 4)
		begin
		we <= 1'b1;
		wd <= data[data_c];
		sda_c = 0;
			if (data_c == 4'd0) state <= WR_ACK;
		data_c = data_c - 1; 
		end
		sda_c = sda_c + 1;
	end
	
	RD_DATA:
	begin
		if (counter == 2)
		begin
		scl <=!scl;
		counter =0;
		end
			counter = counter +1;
		
		if (sda_c == 4)
		begin
		we <= 1'b0;
		rd <= we ? 1'b0 : sda;
		sda_c = 0;
			if (data_c == 4'd0) state <= SEND_ACK;
		data_c = data_c - 1; 
		end
			sda_c = sda_c + 1;
	end
	
	SEND_ACK:
	begin
		if (counter == 2)
		begin
		scl <=!scl;
		counter =0;
		end
			counter = counter +1;
			
		if (sda_c == 4)
		begin
		we <= 1'b1;
		wd <= stop;
		sda_c = 0;
		state <= stop ? ENDING : RD_ACK;
		end
			sda_c = sda_c + 1;
	end
	
	ENDING:
	begin
		if (sda_c < 6)
		begin
			if (counter == 2)
			begin
			scl <=!scl;
			counter =0;
			end
				counter = counter +1;
		end
		
		if (sda_c == 4)
		begin
		we <= 1'b1;
		wd <= 1'b0;
		end
			sda_c = sda_c + 1;
		
		if (sda_c == 7)
		begin
		wd <= 1'bz;
		scl <= 1'b1;
		end
		
		if (sda_c == 12)
		begin
		state <= WAITING;
		end
		
	end
	endcase
end

endmodule 
Соседние файлы в предмете Интерфейсы вычислительных систем