Index: /trunk/MultiChannelUSB/Paella.qsf
===================================================================
--- /trunk/MultiChannelUSB/Paella.qsf	(revision 43)
+++ /trunk/MultiChannelUSB/Paella.qsf	(revision 44)
@@ -52,4 +52,5 @@
 set_global_assignment -name VERILOG_FILE fifo32x12.v
 set_global_assignment -name VERILOG_FILE fifo32x14.v
+set_global_assignment -name VERILOG_FILE analyser.v
 set_global_assignment -name VERILOG_FILE histogram.v
 set_global_assignment -name VERILOG_FILE oscilloscope.v
Index: /trunk/MultiChannelUSB/Paella.v
===================================================================
--- /trunk/MultiChannelUSB/Paella.v	(revision 43)
+++ /trunk/MultiChannelUSB/Paella.v	(revision 44)
@@ -111,32 +111,37 @@
 	reg		[10:0]	tst_counter;	
 
+	reg 			ana_reset [2:0];
+	wire			ana_peak_ready [2:0];
+	wire	[11:0]	ana_peak [2:0];
+
 	reg		[9:0]	osc_counter;	
-	reg 			osc_reset;
 	reg 			osc_byte_num;
-	wire	[9:0]	osc_start_addr;
-	reg 	[9:0]	osc_addr;
-	wire	[15:0]	osc_q;
-
-	reg 			hst_reset;
+
+	reg 			osc_reset_mux, osc_reset [2:0];
+	wire	[9:0]	osc_start_addr [2:0];
+	reg 	[9:0]	osc_start_addr_mux, osc_addr_mux, osc_addr [2:0];
+	wire	[15:0]	osc_q [2:0];
+	reg		[15:0]	osc_q_mux;
+
 	reg 	[1:0]	hst_byte_num;
-	reg 	[11:0]	hst_addr;
-	wire	[31:0]	hst_q;
-
-	reg		[3:0]	state0, state1, state2;
-	reg				adc_fifo_rdreq;
-	wire			adc_fifo_rdempty;
+
+	reg 			hst_reset_mux, hst_reset [2:0];
+	reg 	[11:0]	hst_addr_mux, hst_addr [2:0];
+	wire	[31:0]	hst_q [2:0];
+	reg		[31:0]	hst_q_mux;
+
+	reg		[3:0]	select, state1, state2;
 	reg				adc_fifo_aclr;
 
-	reg		[31:0]	adc_counter;
-	reg				adc_data_ready;
 	wire			adc_clk;
 
 	reg 	[11:0]	adc_data;
 
+	wire			adc_data_ready [2:0];
 	wire 	[11:0]	adc_lvds_data [2:0];
 
-    wire	[11:0]	raw_data;
-    wire	[11:0]	uwt_data;
-    wire	[1:0]	uwt_flag;
+    wire	[11:0]	raw_data [2:0];
+    wire	[11:0]	uwt_data [2:0];
+    wire	[1:0]	uwt_flag [2:0];
  
 	pll pll_unit(
@@ -163,33 +168,55 @@
 		.adc_dc(adc_lvds_data[1]),
 		.adc_dd(adc_lvds_data[2]));
-
-	adc_fifo adc_fifo_unit (
-		.adc_clk(ADC_FCO),
-		.adc_data(adc_lvds_data[1]),
-		.aclr(adc_fifo_aclr),
-		.rdclk(CLK_50MHz),
-		.rdreq(adc_fifo_rdreq),
-		.rdempty(adc_fifo_rdempty),
-		.raw_data(raw_data),
-		.uwt_data({uwt_flag, uwt_data}));
-
-	histogram histogram_unit (
-		.clk(CLK_50MHz),
-		.reset(hst_reset),
-		.data_ready(adc_data_ready),
-		.data(raw_data),
-		.address(hst_addr),
-		.q(hst_q));
+ 
+	genvar i;
+	generate
+		for (i = 0; i < 3; i = i + 1)
+		begin : MCA_CHAIN
+			adc_fifo adc_fifo_unit (
+				.adc_clk(ADC_FCO),
+				.adc_data(adc_lvds_data[i]),
+				.aclr(adc_fifo_aclr),
+				.rdclk(CLK_50MHz),
+				.ready(adc_data_ready[i]),
+				.raw_data(raw_data[i]),
+				.uwt_data({uwt_flag[i], uwt_data[i]}));
 	
-	oscilloscope oscilloscope_unit (
-		.clk(CLK_50MHz),
-		.reset(osc_reset),
-		.data_ready(adc_data_ready),
-		.raw_data(raw_data),
-		.uwt_data(uwt_data),
-		.threshold(16'd100),
-		.address(osc_addr),
-		.start_address(osc_start_addr),
-		.q(osc_q));
+			analyser analyser_unit (
+				.clk(CLK_50MHz),
+				.reset(ana_reset[i]),
+				.data_ready(adc_data_ready[i]),
+				.uwt_flag(uwt_flag[i]),
+				.uwt_data(uwt_data[i]),
+				.peak_ready(ana_peak_ready[i]),
+				.peak(ana_peak[i]));
+/*
+			histogram histogram_unit (
+				.clk(CLK_50MHz),
+				.reset(hst_reset[i]),
+				.data_ready(adc_data_ready[i]),
+				.data(raw_data[i]),
+				.address(hst_addr[i]),
+				.q(hst_q[i]));
+*/
+			histogram histogram_unit (
+				.clk(CLK_50MHz),
+				.reset(hst_reset[i]),
+				.data_ready(ana_peak_ready[i]),
+				.data(ana_peak[i]),
+				.address(hst_addr[i]),
+				.q(hst_q[i]));
+			
+			oscilloscope oscilloscope_unit (
+				.clk(CLK_50MHz),
+				.reset(osc_reset[i]),
+				.data_ready(adc_data_ready[i]),
+				.raw_data(raw_data[i]),
+				.uwt_data(uwt_data[i]),
+				.threshold(16'd100),
+				.address(osc_addr[i]),
+				.start_address(osc_start_addr[i]),
+				.q(osc_q[i]));
+		end
+	endgenerate
 
 /*
@@ -200,28 +227,50 @@
 */
 
-	always @ (posedge CLK_50MHz)
+	always @*
 	begin
-		case (state0)
-			1:
-			begin
-				if (~adc_fifo_rdempty)
-				begin
-//					adc_counter <= adc_counter + 32'd1;
-					adc_fifo_rdreq <= 1'b1;
-					adc_data_ready <= 1'b1;
-					state0 <= 4'd2;
-				end
-			end
-
-			2:
-			begin
-				adc_fifo_rdreq <= 1'b0;
-				adc_data_ready <= 1'b0;
-				state0 <= 4'd1;
-			end
-
+		case(select)
+			4'h0:
+			begin
+				osc_reset[0] = osc_reset_mux;
+				osc_addr[0] = osc_addr_mux;
+				osc_q_mux = osc_q[0];
+				osc_start_addr_mux = osc_start_addr[0];
+				
+				hst_reset[0] = hst_reset_mux;
+				hst_addr[0] = hst_addr_mux;
+				hst_q_mux = hst_q[0];
+			end
+			4'h1:
+			begin
+				osc_reset[1] = osc_reset_mux;
+				osc_addr[1] = osc_addr_mux;
+				osc_q_mux = osc_q[1];
+				osc_start_addr_mux = osc_start_addr[1];
+				
+				hst_reset[1] = hst_reset_mux;
+				hst_addr[1] = hst_addr_mux;
+				hst_q_mux = hst_q[1];
+			end
+			4'h2:
+			begin
+				osc_reset[2] = osc_reset_mux;
+				osc_addr[2] = osc_addr_mux;
+				osc_q_mux = osc_q[2];
+				osc_start_addr_mux = osc_start_addr[2];
+				
+				hst_reset[2] = hst_reset_mux;
+				hst_addr[2] = hst_addr_mux;
+				hst_q_mux = hst_q[2];
+			end
 			default:
 			begin
-				state0 <= 4'd1;
+				osc_reset[0] = osc_reset_mux;
+				osc_addr[0] = osc_addr_mux;
+				osc_q_mux = osc_q[0];
+				osc_start_addr_mux = osc_start_addr[0];
+				
+				hst_reset[0] = hst_reset_mux;
+				hst_addr[0] = hst_addr_mux;
+				hst_q_mux = hst_q[0];
 			end
 		endcase
@@ -252,6 +301,6 @@
 				usb_fifo_rx_rdreq <= 1'b1;
 				usb_fifo_tx_wrreq <= 1'b0;
-				hst_reset <= 1'b0;
-				osc_reset <= 1'b0;
+				hst_reset_mux <= 1'b0;
+				osc_reset_mux <= 1'b0;
 				state1 <= 4'd2;
 			end
@@ -262,37 +311,41 @@
 				begin
 					case (usb_fifo_rx_data)
-						8'h30:
+						8'h40, 8'h41, 8'h42:
 						begin
 							usb_fifo_rx_rdreq <= 1'b0;
-							hst_reset <= 1'b1;
+							hst_reset_mux <= 1'b1;
+							select <= usb_fifo_rx_data[3:0];
 							state1 <= 4'd1;
 						end
-						8'h31:
+						8'h50, 8'h51, 8'h52:
 						begin
 							usb_fifo_rx_rdreq <= 1'b0;
-							hst_addr <= 12'd0;
+							hst_addr_mux <= 12'd0;
 							hst_byte_num <= 2'd0;	
+							select <= usb_fifo_rx_data[3:0];
 							state1 <= 4'd3;
 						end
-						8'h32:
+						8'h60, 8'h61, 8'h62:
 						begin
 							usb_fifo_rx_rdreq <= 1'b0;
-							osc_reset <= 1'b1;
+							osc_reset_mux <= 1'b1;
+							select <= usb_fifo_rx_data[3:0];
 							state1 <= 4'd1;
 						end
-						8'h33:
+						8'h70, 8'h71, 8'h72:
 						begin
 							usb_fifo_rx_rdreq <= 1'b0;
-							osc_addr <= osc_start_addr;
+							osc_addr_mux <= osc_start_addr_mux;
 							osc_counter <= 10'd0;
 							osc_byte_num <= 1'd0;	
+							select <= usb_fifo_rx_data[3:0];
 							state1 <= 4'd6;
 						end
-						8'h34:
+						8'h30:
 						begin
 							usb_fifo_rx_rdreq <= 1'b0;
 							state1 <= 4'd1;
 						end
-						8'h35:
+						8'h31:
 						begin
 							usb_fifo_rx_rdreq <= 1'b0;
@@ -307,5 +360,5 @@
 			3:
 			begin
-				usb_fifo_tx_data <= hst_q[7:0];
+				usb_fifo_tx_data <= hst_q_mux[7:0];
 				usb_fifo_tx_wrreq <= 1'b1;
 				hst_byte_num <= 2'd1;
@@ -317,10 +370,10 @@
 				begin
 					case (hst_byte_num)
-						2'd0: usb_fifo_tx_data <= hst_q[7:0];
-						2'd1: usb_fifo_tx_data <= hst_q[15:8];
-						2'd2: usb_fifo_tx_data <= hst_q[23:16];
-						2'd3: usb_fifo_tx_data <= hst_q[31:24];
+						2'd0: usb_fifo_tx_data <= hst_q_mux[7:0];
+						2'd1: usb_fifo_tx_data <= hst_q_mux[15:8];
+						2'd2: usb_fifo_tx_data <= hst_q_mux[23:16];
+						2'd3: usb_fifo_tx_data <= hst_q_mux[31:24];
 					endcase
-					if ((&hst_byte_num) & (&hst_addr))
+					if ((&hst_byte_num) & (&hst_addr_mux))
 					begin
 						state1 <= 4'd5;
@@ -330,5 +383,5 @@
 						if (&hst_byte_num)
 						begin
-							hst_addr <= hst_addr + 12'd1;
+							hst_addr_mux <= hst_addr_mux + 12'd1;
 						end
 						hst_byte_num <= hst_byte_num + 2'd1;
@@ -348,5 +401,5 @@
 			6:
 			begin
-				usb_fifo_tx_data <= osc_q[7:0];
+				usb_fifo_tx_data <= osc_q_mux[7:0];
 				usb_fifo_tx_wrreq <= 1'b1;
 				osc_byte_num <= 1'd1;
@@ -358,6 +411,6 @@
 				begin
 					case (osc_byte_num)
-						1'd0: usb_fifo_tx_data <= osc_q[7:0];
-						1'd1: usb_fifo_tx_data <= osc_q[15:8];
+						1'd0: usb_fifo_tx_data <= osc_q_mux[7:0];
+						1'd1: usb_fifo_tx_data <= osc_q_mux[15:8];
 					endcase
 					if ((&osc_byte_num) & (&osc_counter))
@@ -369,5 +422,5 @@
 						if (&osc_byte_num)
 						begin
-							osc_addr <= osc_addr + 10'd1;
+							osc_addr_mux <= osc_addr_mux + 10'd1;
 							osc_counter <= osc_counter + 10'd1;
 						end
Index: /trunk/MultiChannelUSB/adc_fifo.v
===================================================================
--- /trunk/MultiChannelUSB/adc_fifo.v	(revision 43)
+++ /trunk/MultiChannelUSB/adc_fifo.v	(revision 44)
@@ -6,6 +6,6 @@
 		input	wire			aclr,
 		input	wire			rdclk,
-		input	wire			rdreq,
-		output	wire			rdempty,
+
+		output	wire			ready,
 		output	wire	[11:0]	raw_data,
 		output	wire	[13:0]	uwt_data
@@ -18,8 +18,12 @@
 
 	wire	[1:0]	wrfull;
+	
+	reg				state;
+	reg				int_rdreq, int_ready;
+	wire			int_rdempty;
 
 	uwt_bior31 #(.L(1)) uwt_1_unit (
 		.clk(adc_clk),
-		.x(adc_data),
+		.x({20'h00000, adc_data}),
 		.d(uwt_d1),
 		.a(uwt_a1),
@@ -48,9 +52,9 @@
 		.data(adc_data),
 		.rdclk(rdclk),
-		.rdreq(rdreq),
+		.rdreq(int_rdreq),
 		.wrclk(adc_clk),
 		.wrreq(~wrfull[0]),
 		.q(raw_data),
-		.rdempty(rdempty),
+		.rdempty(int_rdempty),
 		.wrfull(wrfull[0]));
 
@@ -59,5 +63,5 @@
 		.data({uwt_flag3, uwt_peak3[11:0]}),
 		.rdclk(rdclk),
-		.rdreq(rdreq),
+		.rdreq(int_rdreq),
 		.wrclk(adc_clk),
 		.wrreq(~wrfull[1]),
@@ -66,3 +70,34 @@
 		.wrfull(wrfull[1]));
 
+	always @ (posedge rdclk)
+	begin
+		case (state)
+			1'b0:
+			begin
+				if (~int_rdempty)
+				begin
+					int_rdreq <= 1'b1;
+					int_ready <= 1'b1;
+					state <= 1'b1;
+				end
+			end
+
+			1'b1:
+			begin
+				int_rdreq <= 1'b0;
+				int_ready <= 1'b0;
+				state <= 1'b0;
+			end
+
+			default:
+			begin
+				int_rdreq <= 1'b0;
+				int_ready <= 1'b0;
+				state <= 1'b0;
+			end
+		endcase
+	end
+	
+	assign	ready = int_ready;
+
 endmodule
Index: /trunk/MultiChannelUSB/adc_lvds.v
===================================================================
--- /trunk/MultiChannelUSB/adc_lvds.v	(revision 43)
+++ /trunk/MultiChannelUSB/adc_lvds.v	(revision 44)
@@ -10,8 +10,7 @@
 	);
 
-
 	wire 	[2:0]	int_data_h, int_data_l;
 	reg 	[11:0]	int_data_next [2:0];
-	reg 	[11:0]	int_data [2:0];
+	reg 	[11:0]	int_data_reg [2:0];
 
 	altddio_in #(
@@ -32,7 +31,7 @@
 	always @ (posedge lvds_dco)
 	begin
-		int_data[0] <= int_data_next[0];
-		int_data[1] <= int_data_next[1];
-		int_data[2] <= int_data_next[2];
+		int_data_reg[0] <= int_data_next[0];
+		int_data_reg[1] <= int_data_next[1];
+		int_data_reg[2] <= int_data_next[2];		
 	end
 
@@ -46,7 +45,7 @@
 	always @*
 	begin
-		int_data_next[0] = {int_data[0][9:0], int_data_l[0], int_data_h[0]};
-		int_data_next[1] = {int_data[1][9:0], int_data_l[1], int_data_h[1]};
-		int_data_next[2] = {int_data[2][9:0], int_data_l[2], int_data_h[2]};
+		int_data_next[0] = {int_data_reg[0][9:0], int_data_l[0], int_data_h[0]};
+		int_data_next[1] = {int_data_reg[1][9:0], int_data_l[1], int_data_h[1]};
+		int_data_next[2] = {int_data_reg[2][9:0], int_data_l[2], int_data_h[2]};
 	end
 
Index: /trunk/MultiChannelUSB/analyser.v
===================================================================
--- /trunk/MultiChannelUSB/analyser.v	(revision 44)
+++ /trunk/MultiChannelUSB/analyser.v	(revision 44)
@@ -0,0 +1,105 @@
+module analyser
+	(
+		input	wire			clk, reset,
+		input	wire			data_ready,
+		input	wire	[1:0]	uwt_flag,
+		input	wire	[11:0]	uwt_data,
+		output	wire			peak_ready,
+		output	wire	[11:0]	peak
+	);
+
+	reg		[1:0]	state_reg, state_next;
+	reg		[3:0]	counter_reg, counter_next;
+	reg				peak_ready_reg, peak_ready_next;
+	reg		[11:0]	peak_reg, peak_next;
+	reg		[15:0]	buffer [15:0];
+	wire	[15:0]	sample;
+	wire	[11:0]	baseline;
+
+	integer			i;
+
+	assign	sample = {4'd0, uwt_data};
+	assign	baseline = buffer[15][15:4];
+	
+	always @(posedge clk)
+	begin
+		if (reset)
+		begin
+			state_reg <= 2'd0;
+			counter_reg <= 4'd0;
+			peak_ready_reg <= 1'b0;
+			peak_reg <= 12'd0;
+
+			for(i = 0; i <= 15; i = i + 1)
+			begin
+				buffer[i] <= 12'd0;
+			end
+		end
+		else
+		begin
+			state_reg <= state_next;
+			counter_reg <= counter_next;
+			peak_ready_reg <= peak_ready_next;
+			peak_reg <= peak_next;
+			
+			if (data_ready & uwt_flag[1])
+			begin
+				for(i = 0; i < 15; i = i + 1)
+				begin
+					buffer[i+1] <= buffer[i] + sample;
+				end
+				buffer[0] <= sample;
+			end
+		end
+	end
+	
+	always @*
+	begin
+		state_next = state_reg;
+		counter_next = counter_reg;
+		peak_ready_next = 1'b0;
+		peak_next = 12'd0;
+		case (state_reg)
+			0: // skip first 16 samples
+			begin
+				if (data_ready)
+				begin
+					counter_next = counter_reg + 4'd1;
+					if (&counter_reg)
+					begin
+						state_next <= 2'd1;
+					end
+                end
+ 			end
+
+			1: // skip first 16 minima
+			begin
+				if (data_ready & uwt_flag[1])
+				begin
+					counter_next = counter_reg + 4'd1;
+					if (&counter_reg)
+					begin
+						state_next <= 2'd2;
+					end
+                end
+			end
+
+			2: // calculate peak height
+			begin
+				if (data_ready & uwt_flag[0])
+				begin
+					peak_next = uwt_data - baseline;
+					peak_ready_next = 1'b1;
+                end
+			end
+
+			default:
+			begin
+				state_next = 2'd0;
+			end
+		endcase
+	end
+
+	assign	peak_ready = peak_ready_reg;
+	assign	peak = peak_reg;
+endmodule
Index: /trunk/MultiChannelUSB/fifo32x12.v
===================================================================
--- /trunk/MultiChannelUSB/fifo32x12.v	(revision 43)
+++ /trunk/MultiChannelUSB/fifo32x12.v	(revision 44)
@@ -98,10 +98,7 @@
 		dcfifo_component.lpm_widthu = 5,
 		dcfifo_component.overflow_checking = "ON",
-		dcfifo_component.rdsync_delaypipe = 4,
 		dcfifo_component.underflow_checking = "ON",
-		dcfifo_component.use_eab = "ON",
-		dcfifo_component.write_aclr_synch = "OFF",
-		dcfifo_component.wrsync_delaypipe = 4;
-
+		dcfifo_component.use_eab = "OFF",
+		dcfifo_component.write_aclr_synch = "OFF";
 
 endmodule
Index: /trunk/MultiChannelUSB/fifo32x14.v
===================================================================
--- /trunk/MultiChannelUSB/fifo32x14.v	(revision 43)
+++ /trunk/MultiChannelUSB/fifo32x14.v	(revision 44)
@@ -98,9 +98,7 @@
 		dcfifo_component.lpm_widthu = 5,
 		dcfifo_component.overflow_checking = "ON",
-		dcfifo_component.rdsync_delaypipe = 4,
 		dcfifo_component.underflow_checking = "ON",
-		dcfifo_component.use_eab = "ON",
-		dcfifo_component.write_aclr_synch = "OFF",
-		dcfifo_component.wrsync_delaypipe = 4;
+		dcfifo_component.use_eab = "OFF",
+		dcfifo_component.write_aclr_synch = "OFF";
 
 
Index: /trunk/MultiChannelUSB/fifo32x8.v
===================================================================
--- /trunk/MultiChannelUSB/fifo32x8.v	(revision 43)
+++ /trunk/MultiChannelUSB/fifo32x8.v	(revision 44)
@@ -98,10 +98,7 @@
 		dcfifo_component.lpm_widthu = 5,
 		dcfifo_component.overflow_checking = "ON",
-		dcfifo_component.rdsync_delaypipe = 4,
 		dcfifo_component.underflow_checking = "ON",
-		dcfifo_component.use_eab = "ON",
-		dcfifo_component.write_aclr_synch = "OFF",
-		dcfifo_component.wrsync_delaypipe = 4;
-
+		dcfifo_component.use_eab = "OFF",
+		dcfifo_component.write_aclr_synch = "OFF";
 
 endmodule
