Index: trunk/MultiChannelUSB/i2c_fifo.v
===================================================================
--- trunk/MultiChannelUSB/i2c_fifo.v	(revision 66)
+++ trunk/MultiChannelUSB/i2c_fifo.v	(revision 66)
@@ -0,0 +1,198 @@
+module i2c_fifo
+	(		
+		input	wire			clk, aclr,
+		input	wire			wrreq,
+		input	wire	[15:0]	data,
+		output	wire			full,
+
+		inout	wire			i2c_sda,
+		output	wire			i2c_scl
+	);
+
+	wire			int_rdempty, i2c_clk, start, stop;
+	wire	[15:0]	int_q;
+
+	reg				int_rdreq, int_clken, int_sdo, int_scl, int_ack;
+	reg		[15:0]	int_data;
+	reg		[8:0]	counter;
+	reg		[4:0]	state;
+
+	assign i2c_clk = counter[8];
+
+	assign i2c_sda = int_sdo ? 1'bz : 1'b0;
+	assign i2c_scl = int_scl | (int_clken ? ~i2c_clk : 1'b0);	
+//	assign i2c_scl = counter[8];	
+
+	assign start = int_data[8];
+	assign stop = int_data[9];
+
+	dcfifo #(
+		.intended_device_family("Cyclone III"),
+		.lpm_numwords(16),
+		.lpm_showahead("ON"),
+		.lpm_type("dcfifo"),
+		.lpm_width(16),
+		.lpm_widthu(4),
+		.rdsync_delaypipe(4),
+		.wrsync_delaypipe(4),
+		.overflow_checking("ON"),
+		.underflow_checking("ON"),
+		.use_eab("OFF"),
+		.write_aclr_synch("OFF")) fifo_tx (
+		.aclr(aclr),
+		.data(data),
+		.rdclk(i2c_clk),
+		.rdreq((~int_rdempty) & int_rdreq),
+		.wrclk(clk),
+		.wrreq(wrreq),
+		.q(int_q),
+		.rdempty(int_rdempty),
+		.wrfull(full),
+		.rdfull(),
+		.rdusedw(),
+		.wrempty(),
+		.wrusedw());
+	
+	always @ (posedge clk)
+	begin
+		counter <= counter + 9'd1;
+	end
+
+	always @ (posedge i2c_clk)
+	begin
+		case (state)
+			0:
+			begin
+				int_sdo <= 1'b1;
+				int_scl <= 1'b1;
+				int_rdreq <= 1'b1;
+				state <= 5'd1;
+			end
+
+			1: 
+			begin
+				if (~int_rdempty)
+				begin
+					int_data <= int_q;
+					int_rdreq <= 1'b0;
+					state <= 5'd2;
+				end
+			end
+
+			2: 
+			begin
+				if (start)
+				begin
+					int_sdo <= 1'b1;
+					int_scl <= 1'b1;
+					state <= 5'd3;
+				end
+				else
+				begin
+					state <= 5'd5;
+				end
+			end
+		
+			3:
+			begin // start
+				int_sdo <= 1'b0;
+				state <= 5'd4;
+			end
+
+			4:
+			begin
+				int_scl <= 1'b0;
+				state <= 5'd5;
+			end
+		
+			5:
+			begin // data
+				int_clken <= 1'b1;
+				int_sdo <= int_data[7];
+				state <= 5'd6;
+			end
+
+			6:
+			begin
+				int_sdo <= int_data[6];
+				state <= 5'd7;
+			end
+
+			7:
+			begin
+				int_sdo <= int_data[5];
+				state <= 5'd8;
+			end
+
+			8:
+			begin
+				int_sdo <= int_data[4];
+				state <= 5'd9;
+			end
+
+			9:
+			begin
+				int_sdo <= int_data[3];
+				state <= 5'd10;
+			end
+
+			10:
+			begin
+				int_sdo <= int_data[2];
+				state <= 5'd11;
+			end
+
+			11:
+			begin
+				int_sdo <= int_data[1];
+				state <= 5'd12;
+			end
+
+			12:
+			begin
+				int_sdo <= int_data[0];
+				state <= 5'd13;
+			end
+			
+			13:
+			begin // ack
+				int_sdo <= 1'b1;
+				int_rdreq <= 1'b1;
+				state <= 5'd14;
+			end
+
+			14:
+			begin 
+				int_ack <= i2c_sda;
+				int_rdreq <= 1'b0;
+				if (stop | int_rdempty)
+				begin
+					int_clken <= 1'b0;
+					int_sdo <= 1'b0;
+					int_scl <= 1'b0;
+					state <= 5'd15;
+				end
+				else if (~int_rdempty)
+				begin
+					int_data <= int_q;
+					int_sdo <= int_q[7];
+					state <= 5'd6;
+				end
+			end
+
+			15:
+			begin // stop
+				int_scl <= 1'b1;
+				state <= 5'd16;
+			end
+
+			16:
+			begin
+				int_sdo <= 1'b1;
+				state <= 5'd0;
+			end
+
+		endcase
+	end
+
+endmodule
