// This file is part of the Universal Laboratory (uLab)
//
// © 2017 - 2019 Raptor Engineering, LLC
// All Rights Reserved
//
// Licensed under the terms of the AGPL v3

module control_fpga_top
	(
		// Input clock
		input wire main_12_mhz_clock,

		// Guest FPGA interface
		output wire guest_logic_reset,		// Active high guest logic reset signal

		input wire [3:0] four_bit_output,	// Output from the user program to the remote access module
		output wire [3:0] four_bit_input,	// Input to the user program from the remote access module
		input wire [7:0] eight_bit_output,	// Output from the user program to the remote access module
		output wire [7:0] eight_bit_input,	// Input to the user program from the remote access module
		input wire [15:0] sixteen_bit_output,	// Output from the user program to the remote access module
		output wire [15:0] sixteen_bit_input,	// Input to the user program from the remote access module

		input wire [5:0] lcd_data_in_address,
		input wire [7:0] lcd_data_in_data,
		input wire lcd_data_in_enable,

		input wire [7:0] led_segment_bus,
		input wire [3:0] led_digit_select,

		// Serial interface
		input wire serial_input,
		output wire serial_output,

		// On-board diagnostic LEDs
		output wire [7:0] led_bank
	);

	parameter RAM_ADDR_BITS = 0;

	// Synthesize 50MHz clock from 12MHz clock
	wire main_50_mhz_clock;
	wire pll_locked;

	SB_PLL40_CORE #(
		.FEEDBACK_PATH("SIMPLE"),
		.DIVR(4'b0000),         // DIVR =  0
		.DIVF(7'b1000010),      // DIVF = 66
		.DIVQ(3'b100),          // DIVQ =  4
		.FILTER_RANGE(3'b001)   // FILTER_RANGE = 1
	) system_pll (
		.LOCK(pll_locked),
		.RESETB(1'b1),
		.BYPASS(1'b0),
		.REFERENCECLK(main_12_mhz_clock),
		.PLLOUTCORE(main_50_mhz_clock)
	);

	reg [7:0] diagnostic_led_data = 8'b0;

	//assign led_bank = eight_bit_input;	// Mirror input to the LEDs
	assign led_bank = diagnostic_led_data;	// Show diagnostic data on LEDs

	reg [22:0] slow_clock_divider = 23'b0;
	wire slow_clock;
	reg [1:0] kr_state = 2'b0;
	always @(posedge main_12_mhz_clock) begin
		slow_clock_divider <= slow_clock_divider + 1;
	end
	assign slow_clock = slow_clock_divider[22];

	always @(posedge slow_clock) begin
		kr_state <= kr_state + 1;
		if (pll_locked) begin
			case (kr_state)
				0: diagnostic_led_data <= 8'b00011000;
				1: diagnostic_led_data <= 8'b00100100;
				2: diagnostic_led_data <= 8'b01000010;
				3: diagnostic_led_data <= 8'b10000001;
			endcase
		end else begin
			diagnostic_led_data <= 8'b0;
		end
	end

	// Instantiate main remote access module
	remote_access #(RAM_ADDR_BITS) remote_access(.main_fifty_clock(main_50_mhz_clock), .user_logic_reset(guest_logic_reset), .remote_access_4_bit_output(four_bit_output),
		.remote_access_4_bit_input(four_bit_input), .remote_access_8_bit_output(eight_bit_output),
		.remote_access_8_bit_input(eight_bit_input), .remote_access_16_bit_output(sixteen_bit_output),
		.remote_access_16_bit_input(sixteen_bit_input),
		.serial_port_receiver(serial_input), .serial_port_transmitter(serial_output), .remote_access_input_enable(1'b0),
		.local_input(8'b0), .seize_serial_tx(1'b0), .serial_tx_data(8'b0), .serial_tx_strobe(1'b0),
		.lcd_data_in_address(lcd_data_in_address), .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable),
		.led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select));	
endmodule
