Index: /trunk/MultiChannelUSB/usb_fifo.v
===================================================================
--- /trunk/MultiChannelUSB/usb_fifo.v	(revision 32)
+++ /trunk/MultiChannelUSB/usb_fifo.v	(revision 33)
@@ -11,21 +11,16 @@
 		input	wire	[7:0]	tx_data,
 		output	wire			tx_full, rx_empty,
-		output	wire	[7:0]	rx_data,
+		output	wire	[7:0]	rx_q,
 		output	wire			led
 	);
 
-	// bidirectional data bus
-	reg				int_addr, int_wren, int_rden, int_wrreq, int_rdreq;
-	wire	[7:0]	int_datain = usb_data;
-	wire	[7:0]	int_dataout;
-
-	assign	usb_data = int_wren ? int_dataout : 8'bz;
-
-	wire			rx_full, tx_empty;
-	wire			rx_ready, tx_ready;
+	wire			int_rx_full, int_tx_empty;
+	wire			int_rdreq, int_wrreq, int_pktend;
+	reg				is_rx_addr_ok;
 	reg		[8:0]	byte_counter;
 	reg		[4:0]	idle_counter;
 
-	assign	led = ~usb_empty;
+	wire	[7:0]	int_rx_data = usb_data;
+	wire	[7:0]	int_tx_q;
 
 	fifo32x8 fifo_tx_unit (
@@ -36,107 +31,59 @@
 		.wrclk(clk),
 		.wrreq(tx_wrreq),
-		.q(int_dataout),
-		.rdempty(tx_empty),
+		.q(int_tx_q),
+		.rdempty(int_tx_empty),
 		.wrfull(tx_full));
 
 	fifo32x8 fifo_rx_unit (
 		.aclr(aclr),
-		.data(int_datain),
+		.data(int_rx_data),
 		.rdclk(clk),
 		.rdreq(rx_rdreq),
 		.wrclk(usb_clk),
 		.wrreq(int_rdreq),
-		.q(rx_data),
+		.q(rx_q),
 		.rdempty(rx_empty),
-		.wrfull(rx_full));
+		.wrfull(int_rx_full));
+	
+	assign	rx_ready = (~usb_empty) & (~int_rx_full) & (~int_pktend);
+	assign	tx_ready = (~rx_ready) & (~usb_full) & (~int_tx_empty) & (~int_pktend);
 
-	assign	rx_ready = (~usb_empty) & (~rx_full);
-	assign	tx_ready = (~usb_full) & (~tx_empty);
-		
+	assign	int_rdreq = (rx_ready) & (is_rx_addr_ok);
+	assign	int_wrreq = (tx_ready) & (~is_rx_addr_ok);
+	
+	assign	int_pktend = (&idle_counter);
+
 	always @ (posedge usb_clk)
 	begin
-		casez ({rx_ready, tx_ready, int_addr, int_rden})
-			4'b00??: // idle
-			begin
-				int_addr <= 1'b0;
-				int_rden <= 1'b0;
-				int_wren <= 1'b0;
-				int_rdreq <= 1'b0;
-				int_wrreq <= 1'b0;
-			end
-			4'b1?1?: // set read addr
-			begin
-				int_addr <= 1'b0;
-				int_rden <= 1'b0;
-				int_wren <= 1'b0;
-				int_rdreq <= 1'b0;
-				int_wrreq <= 1'b0;
-			end
-			4'b1?00: // enable reads
-			begin
-				int_addr <= 1'b0;
-				int_rden <= 1'b1;
-				int_wren <= 1'b0;
-				int_rdreq <= 1'b0;
-				int_wrreq <= 1'b0;
-			end
-			4'b1?01: // read
-			begin
-				int_addr <= 1'b0;
-				int_rden <= 1'b1;
-				int_wren <= 1'b0;
-				int_rdreq <= 1'b1;
-				int_wrreq <= 1'b0;
-			end
-			4'b0101: // disable reads
-			begin
-				int_addr <= 1'b0;
-				int_rden <= 1'b0;
-				int_wren <= 1'b0;
-				int_rdreq <= 1'b0;
-				int_wrreq <= 1'b0;
-			end
-			4'b0100: // set write addr
-			begin
-				int_addr <= 1'b1;
-				int_rden <= 1'b0;
-				int_wren <= 1'b1;
-				int_rdreq <= 1'b0;
-				int_wrreq <= 1'b0;
-			end
-			4'b011?: // write
-			begin
-				int_addr <= 1'b1;
-				int_rden <= 1'b0;
-				int_wren <= 1'b1;
-				int_rdreq <= 1'b0;
-				int_wrreq <= 1'b1;
-			end
-		endcase
-/*
-		if (usb_pktend)
+		// respect 1 clock delay between fifo selection
+		// and data transfer operations
+		is_rx_addr_ok <= rx_ready;
+
+		// assert pktend if buffer contains unsent data
+		// and fifo_tx_unit stays empty for more than 30 clocks
+		if (int_pktend)
 		begin
 			byte_counter <= 9'd0;
 			idle_counter <= 5'd0;
 		end
-		else if (usb_wrreq)
+		else if (int_wrreq)
 		begin
 			byte_counter <= byte_counter + 9'd1;
 			idle_counter <= 5'd0;
 		end
-		else if ((|byte_counter) & (tx_empty))
+		else if ((|byte_counter) & (int_tx_empty) & (~rx_ready))
 		begin
 			byte_counter <= byte_counter;
 			idle_counter <= idle_counter + 5'd1;
 		end
-*/
+
 	end
 
-	assign	usb_addr = {1'b1, int_addr}; 
-	assign	usb_rden = int_rden;
+	assign	usb_pktend = int_pktend;
 	assign	usb_rdreq = int_rdreq;
 	assign	usb_wrreq = int_wrreq;
-//	assign	usb_pktend = (&idle_counter);
-	assign	usb_pktend = 1'b0;
+	assign	usb_rden = int_rdreq;
+	assign	usb_addr = {1'b1, ~rx_ready};
+	assign	usb_data = int_wrreq ? int_tx_q : 8'bz;
 
 endmodule
