Index: trunk/MultiChannelUSB/oscilloscope.v
===================================================================
--- trunk/MultiChannelUSB/oscilloscope.v	(revision 84)
+++ trunk/MultiChannelUSB/oscilloscope.v	(revision 90)
@@ -1,181 +1,229 @@
 module oscilloscope
 	(
-		input	wire			clk, reset,
-		input	wire			data_ready, trigger,
-		input	wire	[15:0]  data,
-		input	wire	[9:0]	address,
-		output	wire	[9:0]	start_address,
-		output	wire	[15:0]  q
+		input	wire			clock, frame, reset,
+		
+		input	wire	[16:0]  cfg_data,
+
+		input	wire			trg_flag,
+
+		input	wire	[47:0]	osc_data,
+
+		output	wire			ram_wren,
+		output	wire	[19:0]	ram_addr,
+		inout	wire	[17:0]	ram_data,
+
+		input	wire			bus_ssel, bus_wren,
+		input	wire	[19:0]	bus_addr,
+		input	wire	[15:0]	bus_mosi,
+
+		output	wire	[15:0]	bus_miso,
+		output	wire			bus_busy
 	);
-	
-	// signal declaration
-	reg		[3:0]	state_reg, state_next;
-	reg				wren_reg, wren_next;
-	reg		[9:0]	addr_reg, addr_next;
-	reg		[15:0]	data_reg, data_next;
-
-	reg				trig_reg, trig_next;
-	reg		[9:0]	trig_addr_reg, trig_addr_next;
-	reg		[9:0]	counter_reg, counter_next;
-
-	wire	[15:0]	q_wire;
-
-	altsyncram #(
-		.address_reg_b("CLOCK0"),
-		.clock_enable_input_a("BYPASS"),
-		.clock_enable_input_b("BYPASS"),
-		.clock_enable_output_a("BYPASS"),
-		.clock_enable_output_b("BYPASS"),
-		.intended_device_family("Cyclone III"),
-		.lpm_type("altsyncram"),
-		.numwords_a(1024),
-		.numwords_b(1024),
-		.operation_mode("DUAL_PORT"),
-		.outdata_aclr_b("NONE"),
-		.outdata_reg_b("CLOCK0"),
-		.power_up_uninitialized("FALSE"),
-		.read_during_write_mode_mixed_ports("OLD_DATA"),
-		.widthad_a(10),
-		.widthad_b(10),
-		.width_a(16),
-		.width_b(16),
-		.width_byteena_a(1)) osc_ram_unit(
-		.wren_a(wren_reg),
-		.clock0(clk),
-		.address_a(addr_reg),
-		.address_b(address),
-		.data_a(data_reg),
-		.q_b(q_wire),
-		.aclr0(1'b0),
-		.aclr1(1'b0),
-		.addressstall_a(1'b0),
-		.addressstall_b(1'b0),
-		.byteena_a(1'b1),
-		.byteena_b(1'b1),
-		.clock1(1'b1),
-		.clocken0(1'b1),
-		.clocken1(1'b1),
-		.clocken2(1'b1),
-		.clocken3(1'b1),
-		.data_b({16{1'b1}}),
-		.eccstatus(),
-		.q_a(),
-		.rden_a(1'b1),
-		.rden_b(1'b1),
-		.wren_b(1'b0));
-
-	// body
-	always @(posedge clk)
+
+
+	reg		[47:0]	osc_data_reg, osc_data_next;
+
+	reg		[19:0]	cfg_cntr_max_reg, cfg_cntr_max_next;
+	reg		[19:0]	cfg_cntr_mid_reg, cfg_cntr_mid_next;
+
+	reg		[2:0]	int_case_reg, int_case_next;
+
+	reg				int_trig_reg, int_trig_next;
+	reg		[19:0]	int_trig_addr_reg, int_trig_addr_next;
+	reg		[19:0]	int_cntr_reg, int_cntr_next;
+
+	reg		[15:0]	bus_mosi_reg [2:0];
+	reg		[15:0]	bus_mosi_next [2:0];
+
+	reg		[15:0]	bus_miso_reg, bus_miso_next;
+	reg				bus_busy_reg, bus_busy_next;
+
+	reg				ram_wren_reg [2:0];
+	reg				ram_wren_next [2:0];
+
+	reg		[17:0]	ram_data_reg, ram_data_next;
+	reg		[19:0]	ram_addr_reg, ram_addr_next;
+
+	wire	[17:0]	ram_wren_wire;
+
+	assign	ram_wren = ~ram_wren_reg[0];
+	assign	ram_addr = ram_addr_reg;
+
+	integer i;
+	genvar j;
+
+	generate
+		for (j = 0; j < 18; j = j + 1)
+		begin : SRAM_WREN
+			assign ram_wren_wire[j] = ram_wren_reg[2];
+			assign ram_data[j] = ram_wren_wire[j] ? ram_data_reg[j] : 1'bz;
+		end
+	endgenerate
+
+	always @(posedge clock)
 	begin
 		if (reset)
-        begin
-			state_reg <= 4'b1;
-			wren_reg <= 1'b1;
-			addr_reg <= 10'd0;
-			data_reg <= 16'd0;
-			trig_reg <= 1'b0;
-			trig_addr_reg <= 10'd0;
-			counter_reg <= 10'd0;
+		begin
+			osc_data_reg <= 48'd0;
+			ram_data_reg <= 18'd0;
+			ram_addr_reg <= 20'd0;
+			bus_miso_reg <= 16'd0;
+			bus_busy_reg <= 1'b0;
+			int_case_reg <= 5'd0;
+			int_cntr_reg <= 20'd0;
+			int_trig_reg <= 1'b0;
+			int_trig_addr_reg <= 20'd0;
+			cfg_cntr_max_reg <= 20'd0;
+			cfg_cntr_mid_reg <= 20'd0;
+			
+			for(i = 0; i <= 2; i = i + 1)
+			begin
+				ram_wren_reg[i] <= 1'b0;
+				bus_mosi_reg[i] <= 16'd0;
+			end
 		end
 		else
 		begin
-			state_reg <= state_next;
-			wren_reg <= wren_next;
-			addr_reg <= addr_next;
-			data_reg <= data_next;
-			trig_reg <= trig_next;
-			trig_addr_reg <= trig_addr_next;
-			counter_reg <= counter_next;
+			osc_data_reg <= osc_data_next;
+			ram_data_reg <= ram_data_next;
+			ram_addr_reg <= ram_addr_next;
+			bus_miso_reg <= bus_miso_next;
+			bus_busy_reg <= bus_busy_next;
+			int_case_reg <= int_case_next;
+			int_cntr_reg <= int_cntr_next;
+			int_trig_reg <= int_trig_next;
+			int_trig_addr_reg <= int_trig_addr_next;
+			cfg_cntr_max_reg <= cfg_cntr_max_next;
+			cfg_cntr_mid_reg <= cfg_cntr_mid_next;
+
+			for(i = 0; i <= 2; i = i + 1)
+			begin
+				ram_wren_reg[i] <= ram_wren_next[i];
+				bus_mosi_reg[i] <= bus_mosi_next[i];
+			end
 		end
 	end
+		
 
 	always @*
 	begin
-		state_next = state_reg;
-		wren_next = wren_reg;
-		addr_next = addr_reg;
-		data_next = data_reg;
-		trig_next = trig_reg;
-		trig_addr_next = trig_addr_reg;
-		counter_next = counter_reg;
-
-		case (state_reg)
+
+		osc_data_next = osc_data_reg;
+		ram_data_next = ram_data_reg;
+		ram_addr_next = ram_addr_reg;
+		bus_miso_next = bus_miso_reg;
+		bus_busy_next = bus_busy_reg;
+		int_case_next = int_case_reg;
+		int_cntr_next = int_cntr_reg;
+		int_trig_next = int_trig_reg;
+		int_trig_addr_next = int_trig_addr_reg;
+		cfg_cntr_max_next = cfg_cntr_max_reg;
+		cfg_cntr_mid_next = cfg_cntr_mid_reg;
+
+		for(i = 0; i < 2; i = i + 1)
+		begin
+			ram_wren_next[i+1] = ram_wren_reg[i];
+			bus_mosi_next[i+1] = bus_mosi_reg[i];
+		end
+		ram_wren_next[0] = 1'b0;
+		bus_mosi_next[0] = 16'd0;
+
+		case (int_case_reg)
 			0:
 			begin
-				// nothing to do 
-				state_next = 4'b0;
-				wren_next = 1'b0;
-				addr_next = 10'd0;
-				data_next = 16'd0;
-				counter_next = 10'd0;
-			end
-			
+				ram_data_next = 18'd0;
+				ram_addr_next = 20'd0;
+				bus_busy_next = 1'b0;
+				int_cntr_next = 20'd0;
+				int_trig_next = 1'b0;
+
+				ram_data_next = {bus_mosi_reg[1][15:8], 1'b0, bus_mosi_reg[1][7:0], 1'b0};
+
+				if (bus_ssel)
+				begin
+					bus_miso_next = {ram_data[17:10], ram_data[8:1]};
+					ram_wren_next[0] = bus_wren;
+					if (bus_wren)
+					begin
+						ram_addr_next = bus_addr;
+						bus_mosi_next[0] = bus_mosi;
+					end
+					else
+					begin
+//						ram_addr_next = int_trig_addr_reg + bus_addr;	
+						ram_addr_next = bus_addr;	
+					end
+				end
+				else if (cfg_data[16])
+				begin
+					// start recording
+					ram_wren_next[0] = 1'b1;
+					bus_busy_next = 1'b1;
+					int_case_next = 3'd1;
+					int_trig_addr_next = 20'd0;
+					cfg_cntr_max_next = {cfg_data[7:0], 10'd0};
+					cfg_cntr_mid_next = {cfg_data[15:8], 10'd0};
+				end
+
+			end
+
+			// sample recording
 			1:
 			begin
-				// write zeros
-				if (&addr_reg)
-				begin
-					wren_next = 1'b0;
-					state_next = 4'd2;
-				end
-				else
-				begin
-					addr_next = addr_reg + 10'd1;
-				end
-			end
-	
+				ram_wren_next[0] = 1'b1;
+				if (frame)
+				begin
+					osc_data_next = osc_data;
+					ram_addr_next = ram_addr_reg + 20'd1;
+					int_case_next = 3'd2;
+
+					if ((~int_trig_reg) & (trg_flag) &
+						(int_cntr_reg == cfg_cntr_mid_reg))
+					begin
+						int_trig_next = 1'b1;
+						int_trig_addr_next = ram_addr_reg;
+					end
+					
+					if (int_trig_reg | (int_cntr_reg < cfg_cntr_mid_reg))
+					begin
+						int_cntr_next = int_cntr_reg + 20'd1;
+					end
+				end
+			end
+
 			2:
 			begin
-				if (data_ready)
-				begin
-					wren_next = 1'b1;
-					data_next = data;
-					state_next = 4'd3;
-				end
+				ram_wren_next[0] = 1'b1;
+				ram_data_next = {osc_data_reg[15:8], 1'b0, osc_data_reg[7:0], 1'b0};
+				ram_addr_next = ram_addr_reg + 20'd1;
+				int_case_next = 3'd3;
 			end
 
 			3:
 			begin
-				// stop write
-				wren_next = 1'b0;
-				addr_next = addr_reg + 10'd1;
-
-				if (&counter_reg)
-				begin
-					state_next = 4'd0;
-				end
-				else
-				begin
-					state_next = 4'd2;
-
-					if ((~trig_reg) & (trigger) 
-						& (counter_reg == 10'd512))
-					begin
-						// trigger
-						trig_next = 1'b1;
-						trig_addr_next = addr_reg;
-					end
-					
-					if (trig_reg | (counter_reg < 10'd512))
-					begin
-						counter_next = counter_reg + 10'd1;
-					end
-				end
-			end
-
-			default:
-			begin
-				state_next = 4'b0;
-				wren_next = 1'b0;
-				addr_next = 10'd0;
-				data_next = 16'd0;
-				counter_next = 10'd0;
-			end
+				ram_wren_next[0] = 1'b1;
+				ram_data_next = {osc_data_reg[31:24], 1'b0, osc_data_reg[23:16], 1'b0};
+				ram_addr_next = ram_addr_reg + 20'd1;
+				int_case_next = 3'd4;
+			end
+
+			4:
+			begin
+				ram_wren_next[0] = 1'b1;
+				ram_data_next = {osc_data_reg[47:40], 1'b0, osc_data_reg[39:32], 1'b0};
+				int_case_next = 3'd1;
+				if (int_cntr_reg >= cfg_cntr_max_reg)
+				begin
+					ram_wren_next[0] = 1'b0;
+					ram_addr_next = 20'd0;
+					int_case_next = 3'd0;
+				end
+			end
+
 		endcase
 	end
 
-	// output logic
-	assign	q = q_wire;
-	assign	start_address = trig_reg ? (trig_addr_reg ^ 10'h200) + 10'd1: addr_reg + 10'd1;
+	assign bus_miso = bus_miso_reg;
+	assign bus_busy = bus_busy_reg;
 
 endmodule
