module top
	(
		input	wire			CLK_100MHz,
		output	wire			LED,

		input	wire			ADC_DCO,
		input	wire			ADC_FCO,
		input	wire	[5:0]	ADC_D,

		output	wire			USB_SLRD,
		output	wire			USB_SLWR,
		input	wire			USB_IFCLK,
		input	wire			USB_FLAGA, // EMPTY flag for EP6
		input	wire			USB_FLAGB, // FULL flag for EP8
		output	wire			USB_PA2,
		output	wire			USB_PA4,
		output	wire			USB_PA6,
		inout	wire	[7:0]	USB_PB,

		output	wire			RAM_CLK,
		output	wire			RAM_WE,
		output	wire	[21:0]	RAM_ADDR,
		inout	wire			RAM_DQAP,
		inout	wire	[7:0]	RAM_DQA,
		inout	wire			RAM_DQBP,
		inout	wire	[7:0]	RAM_DQB
	);

	//	Turn output ports off
/*
	assign	RAM_CLK		=	1'b0;
	assign	RAM_CE1		=	1'b0;
	assign	RAM_WE		=	1'b0;
	assign	RAM_ADDR	=	20'h00000;
*/

	assign	RAM_CLK = sys_clock;

	assign	USB_PA2		=	~usb_rden;
	assign	USB_PA4		=	usb_addr;
	assign	USB_PA6		=	~usb_pktend;

	wire			usb_wrreq, usb_rdreq, usb_rden, usb_pktend;
	wire			usb_tx_wrreq, usb_rx_rdreq;
	wire			usb_tx_full, usb_rx_empty;
	wire	[7:0]	usb_tx_data, usb_rx_data;
	wire			usb_addr;

	assign	USB_SLRD = ~usb_rdreq;
	assign	USB_SLWR = ~usb_wrreq;

	usb_fifo usb_unit
	(
		.usb_clock(USB_IFCLK),
		.usb_data(USB_PB),
		.usb_full(~USB_FLAGB),
		.usb_empty(~USB_FLAGA),
		.usb_wrreq(usb_wrreq),
		.usb_rdreq(usb_rdreq),
		.usb_rden(usb_rden),
		.usb_pktend(usb_pktend),
		.usb_addr(usb_addr),

		.clock(sys_clock),

		.tx_full(usb_tx_full),
		.tx_wrreq(usb_tx_wrreq),
		.tx_data(usb_tx_data),

		.rx_empty(usb_rx_empty),
		.rx_rdreq(usb_rx_rdreq),
		.rx_q(usb_rx_data)
	);

	wire			sys_clock;

	sys_pll sys_pll_unit(
		.inclk0(CLK_100MHz),
		.c0(sys_clock));

	wire	[15:0]		cfg_bits [63:0];
	wire	[1023:0]	int_cfg_bits;

	wire 			cfg_reset;

	wire 	[2:0]	bus_ssel;
	wire			bus_wren;
	wire	[31:0]	bus_addr;
	wire	[15:0]	bus_mosi;
	wire 	[15:0]	bus_miso [2:0];
	wire 	[2:0]	bus_busy;

	wire 	[15:0]	mrg_bus_miso;
	wire 			mrg_bus_busy;

	wire 	[3*16-1:0]	int_bus_miso;

	genvar j;

	generate
		for (j = 0; j < 64; j = j + 1)
		begin : CONFIGURATION_OUTPUT
			assign cfg_bits[j] = int_cfg_bits[j*16+15:j*16];
		end
	endgenerate

	configuration configuration_unit (
		.clock(sys_clock),
		.reset(cfg_reset),
		.bus_ssel(bus_ssel[0]),
		.bus_wren(bus_wren),
		.bus_addr(bus_addr[5:0]),
		.bus_mosi(bus_mosi),
		.bus_miso(bus_miso[0]),
		.bus_busy(bus_busy[0]),
		.cfg_bits(int_cfg_bits));

	generate
		for (j = 0; j < 3; j = j + 1)
		begin : BUS_OUTPUT
			assign int_bus_miso[j*16+15:j*16] = bus_miso[j];
		end
	endgenerate

	lpm_mux #(
		.lpm_size(3),
		.lpm_type("LPM_MUX"),
		.lpm_width(16),
		.lpm_widths(2)) bus_miso_mux_unit (
		.sel(bus_addr[29:28]),
		.data(int_bus_miso),
		.result(mrg_bus_miso));

	lpm_mux #(
		.lpm_size(3),
		.lpm_type("LPM_MUX"),
		.lpm_width(1),
		.lpm_widths(2)) bus_busy_mux_unit (
		.sel(bus_addr[29:28]),
		.data(bus_busy),
		.result(mrg_bus_busy));

	lpm_decode #(
		.lpm_decodes(3),
		.lpm_type("LPM_DECODE"),
		.lpm_width(2)) lpm_decode_unit (
		.data(bus_addr[29:28]),
		.eq(bus_ssel));


	control control_unit (
		.clock(sys_clock),
		.rx_empty(usb_rx_empty),
		.tx_full(usb_tx_full),
		.rx_data(usb_rx_data),
		.rx_rdreq(usb_rx_rdreq),
		.tx_wrreq(usb_tx_wrreq),
		.tx_data(usb_tx_data),
		.bus_wren(bus_wren),
		.bus_addr(bus_addr),
		.bus_mosi(bus_mosi),
		.bus_miso(mrg_bus_miso),
		.bus_busy(mrg_bus_busy),
		.led(LED));

endmodule
