/*
 * top.v
 *
 * vim: ts=4 sw=4
 *
 * Top-level for the icE1usb production boards
 *
 * Copyright (C) 2019-2020  Sylvain Munaut <tnt@246tNt.com>
 * SPDX-License-Identifier: CERN-OHL-S-2.0
 */

`default_nettype none

module top (
	// E1 PHY
	input  wire e1A_rx_hi_p,
//	input  wire e1A_rx_hi_n,
	input  wire e1A_rx_lo_p,
//	input  wire e1A_rx_lo_n,
	output wire e1A_tx_hi,
	output wire e1A_tx_lo,

	input  wire e1B_rx_hi_p,
//	input  wire e1B_rx_hi_n,
	input  wire e1B_rx_lo_p,
//	input  wire e1B_rx_lo_n,
	output wire e1B_tx_hi,
	output wire e1B_tx_lo,

	output wire [1:0] e1_rx_bias,

	// USB
	inout  wire usb_dp,
	inout  wire usb_dn,
	output wire usb_pu,

	// Flash
	inout  wire flash_mosi,
	inout  wire flash_miso,
	inout  wire flash_clk,
	inout  wire flash_cs_n,

	// LED Shift register + Button input
	inout  wire e1_led_rclk,

	// GPS
	output wire gps_reset_n,
	input  wire gps_rx,
	output wire gps_tx,
	input  wire gps_pps,

	// I2C
	inout  wire i2c_sda,
	inout  wire i2c_scl,

	// GPIOs
	inout  wire [2:0] gpio,

	// Clock (30.72 MHz)
	input  wire clk_in,
	output wire clk_tune_hi,
	output wire clk_tune_lo,

	// Debug UART
	input  wire dbg_rx,
	output wire dbg_tx,

	// RGB LEDs
	output wire [2:0] rgb
);

	localparam integer WB_N = 3;

	genvar i;


	// Signals
	// -------

	// Flash SPI internal signals
	wire flash_mosi_i,  flash_miso_i,  flash_clk_i;
	wire flash_mosi_o,  flash_miso_o,  flash_clk_o;
	wire flash_mosi_oe, flash_miso_oe, flash_clk_oe;
	wire flash_csn_o;

	// Peripheral wishbone
	wire     [15:0] wb_addr;
	wire     [31:0] wb_rdata [0:WB_N-1];
	wire     [31:0] wb_wdata;
	wire     [ 3:0] wb_wmsk;
	wire            wb_we;
	wire [WB_N-1:0] wb_cyc;
	wire [WB_N-1:0] wb_ack;

	wire [(WB_N*32)-1:0] wb_rdata_flat;

	// Ticks
	wire [1:0] tick_e1_rx;
	wire [1:0] tick_e1_tx;
	wire       tick_usb_sof;

	// I2C
	wire i2c_scl_oe;
	wire i2c_sda_oe;
	wire i2c_sda_i;

	// Led & Button
	wire [7:0] e1_led_state;
	wire       e1_led_run;
	wire       e1_led_active;

	wire       spi_req;
	wire       spi_gnt;

	wire [7:0] sr_val;
	wire       sr_go;
	wire       sr_rdy;

	wire       btn_val;
	wire       btn_stb;

	// Clocks / Reset
	wire rst_req;

	wire clk_sys;
	wire rst_sys;
	wire clk_48m;
	wire rst_48m;


	// SoC base
	// --------

	// Instance
	soc_base #(
		.WB_N(WB_N),
		.E1_N(2),
		.E1_UNIT_HAS_RX(2'b01),
		.E1_UNIT_HAS_TX(2'b01),
		.E1_LIU(0)
	) soc_I (
		.e1_rx_hi_p   ({e1B_rx_hi_p, e1A_rx_hi_p}),
//		.e1_rx_hi_n   ({e1B_rx_hi_n, e1A_rx_hi_n}),
		.e1_rx_lo_p   ({e1B_rx_lo_p, e1A_rx_lo_p}),
//		.e1_rx_lo_n   ({e1B_rx_lo_n, e1A_rx_lo_n}),
		.e1_tx_hi     ({e1B_tx_hi,   e1A_tx_hi  }),
		.e1_tx_lo     ({e1B_tx_lo,   e1A_tx_lo  }),
		.e1_rx_data   (),
		.e1_rx_clk    (),
		.e1_tx_data   (),
		.e1_tx_clk    (),
		.usb_dp       (usb_dp),
		.usb_dn       (usb_dn),
		.usb_pu       (usb_pu),
		.flash_mosi_i (flash_mosi_i),
		.flash_mosi_o (flash_mosi_o),
		.flash_mosi_oe(flash_mosi_oe),
		.flash_miso_i (flash_miso_i),
		.flash_miso_o (flash_miso_o),
		.flash_miso_oe(flash_miso_oe),
		.flash_clk_i  (flash_clk_i),
		.flash_clk_o  (flash_clk_o),
		.flash_clk_oe (flash_clk_oe),
		.flash_csn_o  (flash_csn_o),
		.dbg_rx       (dbg_rx),
		.dbg_tx       (dbg_tx),
		.rgb          (rgb),
		.wb_m_addr    (wb_addr),
		.wb_m_rdata   (wb_rdata_flat),
		.wb_m_wdata   (wb_wdata),
		.wb_m_wmsk    (wb_wmsk),
		.wb_m_we      (wb_we),
		.wb_m_cyc     (wb_cyc),
		.wb_m_ack     (wb_ack),
		.tick_e1_rx   (tick_e1_rx),
		.tick_e1_tx   (tick_e1_tx),
		.tick_usb_sof (tick_usb_sof),
		.clk_sys      (clk_sys),
		.rst_sys      (rst_sys),
		.clk_48m      (clk_48m),
		.rst_48m      (rst_48m)
	);

	// WB read data flattening
	for (i=0; i<WB_N; i=i+1)
		assign wb_rdata_flat[i*32+:32] = wb_rdata[i];


	// Dummy channel
	// -------------

	wire [1:0] e1_dummy;

	SB_IO #(
		.PIN_TYPE(6'b000000),
		.PULLUP(1'b0),
		.NEG_TRIGGER(1'b0),
		.IO_STANDARD("SB_LVDS_INPUT")
	) e1_dummy_rx_I[1:0] (
		.PACKAGE_PIN({e1B_rx_hi_p, e1B_rx_lo_p}),
		.LATCH_INPUT_VALUE(1'b0),
		.CLOCK_ENABLE(1'b1),
		.INPUT_CLK(clk_sys),
		.OUTPUT_CLK(1'b0),
		.OUTPUT_ENABLE(1'b0),
		.D_OUT_0(1'b0),
		.D_OUT_1(1'b0),
		.D_IN_0(e1_dummy),
		.D_IN_1()
	);

	SB_IO #(
		.PIN_TYPE(6'b010100),
		.PULLUP(1'b0),
		.NEG_TRIGGER(1'b0),
		.IO_STANDARD("SB_LVCMOS")
	) e1_dummy_tx_I[1:0] (
		.PACKAGE_PIN({e1B_tx_hi, e1B_tx_lo}),
		.LATCH_INPUT_VALUE(1'b0),
		.CLOCK_ENABLE(1'b1),
		.INPUT_CLK(1'b0),
		.OUTPUT_CLK(clk_sys),
		.OUTPUT_ENABLE(1'b0),
		.D_OUT_0(e1_dummy),
		.D_OUT_1(1'b0),
		.D_IN_0(),
		.D_IN_1()
	);


	// Misc [0]
	// ----

	misc misc_I (
		.e1_rx_bias    (e1_rx_bias),
		.clk_tune_hi   (clk_tune_hi),
		.clk_tune_lo   (clk_tune_lo),
		.gps_reset_n   (gps_reset_n),
		.gps_pps       (gps_pps),
		.gpio          (gpio),
		.e1_led_state  (e1_led_state),
		.e1_led_run    (e1_led_run),
		.e1_led_active (e1_led_active),
		.btn_val       (btn_val),
		.btn_stb       (btn_stb),
		.tick_e1_rx    (tick_e1_rx),
		.tick_e1_tx    (tick_e1_tx),
		.tick_usb_sof  (tick_usb_sof),
		.rst_req       (rst_req),
		.wb_addr       (wb_addr[7:0]),
		.wb_rdata      (wb_rdata[0]),
		.wb_wdata      (wb_wdata),
		.wb_we         (wb_we),
		.wb_cyc        (wb_cyc[0]),
		.wb_ack        (wb_ack[0]),
		.clk           (clk_sys),
		.rst           (rst_sys)
	);


	// GPS UART [1]
	// --------

	uart_wb #(
		.DIV_WIDTH(12),
		.DW(32)
	) gps_uart_I (
		.uart_tx  (gps_tx),
		.uart_rx  (gps_rx),
		.wb_addr  (wb_addr[1:0]),
		.wb_rdata (wb_rdata[1]),
		.wb_wdata (wb_wdata),
		.wb_we    (wb_we),
		.wb_cyc   (wb_cyc[1]),
		.wb_ack   (wb_ack[1]),
		.clk      (clk_sys),
		.rst      (rst_sys)
	);


	// I2C [2]
	// ---

	// Controller
	i2c_master_wb #(
		.DW(3),
		.FIFO_DEPTH(0)
	) i2c_I (
		.scl_oe  (i2c_scl_oe),
		.sda_oe  (i2c_sda_oe),
		.sda_i   (i2c_sda_i),
		.wb_rdata(wb_rdata[2]),
		.wb_wdata(wb_wdata),
		.wb_we   (wb_we),
		.wb_cyc  (wb_cyc[2]),
		.wb_ack  (wb_ack[2]),
		.ready   (),
		.clk     (clk_sys),
		.rst     (rst_sys)
	);

	// IOBs
	SB_IO #(
		.PIN_TYPE(6'b110101),
		.PULLUP(1'b1),
		.IO_STANDARD("SB_LVCMOS")
	) i2c_scl_iob_I (
		.PACKAGE_PIN  (i2c_scl),
		.OUTPUT_CLK   (clk_sys),
		.OUTPUT_ENABLE(i2c_scl_oe),
		.D_OUT_0      (1'b0)
	);

	SB_IO #(
		.PIN_TYPE(6'b110100),
		.PULLUP(1'b1),
		.IO_STANDARD("SB_LVCMOS")
	) i2c_sda_iob_I (
		.PACKAGE_PIN  (i2c_sda),
		.INPUT_CLK    (clk_sys),
		.OUTPUT_CLK   (clk_sys),
		.OUTPUT_ENABLE(i2c_sda_oe),
		.D_OUT_0      (1'b0),
		.D_IN_0       (i2c_sda_i)
	);


	// E1 LEDs & Button
	// ----------------

	// Blink pattern generator
	led_blinker blinker_I (
		.led_state(e1_led_state),
		.sr_val   (sr_val),
		.sr_go    (sr_go),
		.sr_rdy   (sr_rdy),
		.clk      (clk_sys),
		.rst      (rst_sys)
	);

	// Interface
	sr_btn_if #(
		.TICK_LOG2_DIV(3)
	) spi_mux_I (
		.flash_mosi  (flash_mosi),
		.flash_miso  (flash_miso),
		.flash_clk   (flash_clk),
		.flash_cs_n  (flash_cs_n),
		.e1_led_rclk (e1_led_rclk),
		.spi_mosi_i  (flash_mosi_i),
		.spi_mosi_o  (flash_mosi_o),
		.spi_mosi_oe (flash_mosi_oe),
		.spi_miso_i  (flash_miso_i),
		.spi_miso_o  (flash_miso_o),
		.spi_miso_oe (flash_miso_oe),
		.spi_clk_i   (flash_clk_i),
		.spi_clk_o   (flash_clk_o),
		.spi_clk_oe  (flash_clk_oe),
		.spi_csn_o   (flash_csn_o),
		.spi_csn_oe  (1'b1),
		.spi_req     (spi_req),
		.spi_gnt     (spi_gnt),
		.sr_val      (sr_val),
		.sr_go       (sr_go),
		.sr_rdy      (sr_rdy),
		.btn_val     (btn_val),
		.btn_stb     (btn_stb),
		.clk         (clk_sys),
		.rst         (rst_sys)
	);

	assign spi_req = ~e1_led_run;
	assign e1_led_active = ~spi_gnt;


	// Clock / Reset
	// -------------

	sysmgr sys_mgr_I (
		.clk_in (clk_in),
		.rst_in (rst_req),
		.clk_sys(clk_sys),
		.rst_sys(rst_sys),
		.clk_48m(clk_48m),
		.rst_48m(rst_48m)
	);

endmodule // top
