----------------------------------------------------------------------------------
--
-- Copyright CERN 2011.
--
-- This documentation describes Open Hardware and is licensed under the
-- CERN OHL v. 1.1.
--
-- You may redistribute and modify this documentation under the terms of the CERN
-- OHL v.1.1. (http://ohwr.org/cernohl).
--
-- This documentation is distributed WITHOUT
-- ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY
-- QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN OHL v.1.1 for
-- applicable conditions.
--
----------------------------------------------------------------------------------
--
-- Company:        CERN, BE-CO-HT
-- Engineer:       Carlos Gil Soriano
--
-- Create Date:
-- Design Name:
-- Module Name:
-- Project Name:
-- Target Devices: Spartan 6
-- Tool versions:  Xilinx ISE 13.4
-- Description:
--
-- Dependencies:
--
-- Revision: 0.1
--   0.01          + File Created
--
-- Additional Comments:
--
----------------------------------------------------------------------------------

library IEEE;
library work;

use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

use work.image1_pkg.ALL;
use work.rs485_pkg.ALL;
use work.bicolor_led_ctrl_pkg.ALL;

entity rs485_top is
   generic(g_NUMBER_OF_CHANNELS : NATURAL := work.rs485_pkg.c_NUMBER_OF_CHANNELS);
   port(FPGA_CLK_P           : in  STD_LOGIC;
        FPGA_CLK_N           : in  STD_LOGIC;
        CLK20_VCXO           : in  STD_LOGIC;
        LED_CTRL0            : out STD_LOGIC;
        LED_CTRL0_OEN        : out STD_LOGIC;
        LED_CTRL1            : out STD_LOGIC;
        LED_CTRL1_OEN        : out STD_LOGIC;
        LED_MULTICAST_2_0    : out STD_LOGIC;
        LED_MULTICAST_3_1    : out STD_LOGIC;
        LED_WR_GMT_TTL_TTLN  : out STD_LOGIC;
        LED_WR_LINK_SYSERROR : out STD_LOGIC;
        LED_WR_OK_SYSPW      : out STD_LOGIC;
        LED_WR_OWNADDR_I2C   : out STD_LOGIC;
        PULSE_FRONT_LED_N  : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
        PULSE_REAR_LED     : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
        FPGA_INPUT_TTL_N   : in  STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
        FPGA_OUT_TTL       : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
        FPGA_RS485_INA_TTL : in  STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
        FPGA_RS485_INB_TTL : in  STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
        FPGA_TRIG_RTM      : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
        INV_IN_N           : in  STD_LOGIC_VECTOR(4 downto 1);
        INV_OUT            : out STD_LOGIC_VECTOR(4 downto 1);
        SCL_I              : in  STD_LOGIC;
        SCL_O              : out STD_LOGIC;
        SCL_OE             : out STD_LOGIC;
        SDA_I              : in  STD_LOGIC;
        SDA_O              : out STD_LOGIC;
        SDA_OE             : out STD_LOGIC;
        FPGA_GA            : in  STD_LOGIC_VECTOR(4 downto 0);
        FPGA_GAP           : in  STD_LOGIC;
        FPGA_PROM_CCLK     : out STD_LOGIC;
        FPGA_PROM_CSO_B_N  : out STD_LOGIC;
        FPGA_PROM_DIN      : in  STD_LOGIC;
        FPGA_PROM_MOSI     : out STD_LOGIC;
        FPGA_OE            : out STD_LOGIC;
        FPGA_RS485_OE      : out STD_LOGIC;
        FPGA_TRIG_TTL_OE   : out STD_LOGIC;
        FPGA_INV_OE        : out STD_LOGIC;
        TTL_or_INV_TTL_N   : in  STD_LOGIC;
        RST                : in  STD_LOGIC;
        FPGA_RTMM          : in  STD_LOGIC_VECTOR(2 downto 0);
        FPGA_RTMP          : in  STD_LOGIC_VECTOR(2 downto 0));
end rs485_top;

architecture Behavioral of rs485_top is

   --! TODO: connect to Matthieu's LEDs IP core
   signal s_leds_array_image1    : t_leds_array;
   signal s_led_state_array     : t_led_state_array(
                                      c_NB_ARRAY_LEDS - 1 downto 0);
   signal s_pulse_i_rear : STD_LOGIC_VECTOR(6 downto 1);

   signal s_rst_n        : STD_LOGIC := '0';

begin

--   g_rs485_inputs: for i in 1 to 6 generate
--   begin
--      inst_125m_IBUFDS : IBUFDS
--      generic map (DIFF_TERM    => TRUE,  IBUF_LOW_PWR => TRUE)
--      port map (O  => s_pulse_i_rear(i), I  => FPGA_RS485_INA_TTL(i),
--                                         IB => FPGA_RS485_INB_TTL(i));
--   end generate;

   inst_image1_top:  image1_top
   generic map(g_NUMBER_OF_CHANNELS => g_NUMBER_OF_CHANNELS)
   port map(FPGA_CLK_P          => FPGA_CLK_P,
            FPGA_CLK_N          => FPGA_CLK_N,
            led_pw_o            => s_leds_array_image1.top.PWR,
            led_err_o           => s_leds_array_image1.top.ERR,
            led_ttl_o           => s_leds_array_image1.top.TTL_N,
            led_o_front         => PULSE_FRONT_LED_N,
            led_o_rear          => PULSE_REAR_LED,
            pulse_i_front       => FPGA_INPUT_TTL_N,
            pulse_o_front       => FPGA_OUT_TTL,
            pulse_i_rear        => FPGA_RS485_INA_TTL,
            pulse_o_rear        => FPGA_TRIG_RTM,
            inv_i               => INV_IN_N,
            inv_o               => INV_OUT,
            SCL_I               => SCL_I,
            SCL_O               => SCL_O,
            SCL_OE              => SCL_OE,
            SDA_I               => SDA_I,
            SDA_O               => SDA_O,
            SDA_OE              => SDA_OE,
            FPGA_GA             => FPGA_GA ,
            FPGA_GAP            => FPGA_GAP,
            FPGA_PROM_CCLK      => FPGA_PROM_CCLK,
            FPGA_PROM_CSO_B_N   => FPGA_PROM_CSO_B_N,
            FPGA_PROM_DIN       => FPGA_PROM_DIN,
            FPGA_PROM_MOSI      => FPGA_PROM_MOSI,
            led_link_up_o       => s_leds_array_image1.middle.WR_LINK,
            led_pps_o           => s_leds_array_image1.middle.WR_GMT,
            led_wr_ok_o         => s_leds_array_image1.middle.WR_OK,
            fpga_o_en           => FPGA_OE,
            fpga_o_blo_en       => FPGA_RS485_OE,
            fpga_o_ttl_en       => FPGA_TRIG_TTL_OE,
            fpga_o_inv_en       => FPGA_INV_OE,
            level               => TTL_or_INV_TTL_N,
            switch_i            => RST,
            manual_rst_n_o      => open, --! We don't have MR_N in RS485
            FPGA_RTMM           => FPGA_RTMM,
            FPGA_RTMP           => FPGA_RTMP);

   --! Here are organized in the same disposition as in the front panel.
   --! Take a look to rs485_pkg.vhd for the correct order for
   --! bicolor_led_ctrl
   s_led_state_array(c_LED_NB_PWR)    <= f_LED_STATE(c_LED_COLOR_PWR)
                                        when s_leds_array_image1.top.PWR = '1'
                                        else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_ERR)    <= f_LED_STATE(c_LED_COLOR_ERR)
                                        when s_leds_array_image1.top.ERR = '1'
                                        else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_TTL_N)  <= f_LED_STATE(c_LED_COLOR_TTL_N)
                                        when s_leds_array_image1.top.TTL_N = '1'
                                        else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_I2C)    <= f_LED_STATE(c_LED_COLOR_I2C)
                                        when s_leds_array_image1.top.I2C = '1'
                                        else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_WR_OK)   <= f_LED_STATE(c_LED_COLOR_WR_OK)
                                  when s_leds_array_image1.middle.WR_OK = '1'
                                  else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_WR_LINK) <= f_LED_STATE(c_LED_COLOR_WR_LINK)
                                  when s_leds_array_image1.middle.WR_LINK = '1'
                                  else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_WR_GMT)  <= f_LED_STATE(c_LED_COLOR_WR_GMT)
                                  when s_leds_array_image1.middle.WR_GMT = '1'
                                  else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_WR_ADDR) <= f_LED_STATE(c_LED_COLOR_WR_ADDR)
                                  when s_leds_array_image1.middle.WR_ADDR = '1'
                                  else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_MULTICAST3) <= f_LED_STATE(c_LED_COLOR_MULTICAST3)
                                  when s_leds_array_image1.bottom.MULTICAST(3) = '1'
                                  else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_MULTICAST2) <= f_LED_STATE(c_LED_COLOR_MULTICAST2)
                                  when s_leds_array_image1.bottom.MULTICAST(2) = '1'
                                  else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_MULTICAST1) <= f_LED_STATE(c_LED_COLOR_MULTICAST1)
                                  when s_leds_array_image1.bottom.MULTICAST(1) = '1'
                                  else f_LED_STATE(c_LED_OFF);
   s_led_state_array(c_LED_NB_MULTICAST0) <= f_LED_STATE(c_LED_COLOR_MULTICAST0)
                                  when s_leds_array_image1.bottom.MULTICAST(0) = '1'
                                  else f_LED_STATE(c_LED_OFF);
   s_rst_n   <= not(RST);

   inst_bicolor_led_ctrl: bicolor_led_ctrl
   port map(rst_n_i         => s_rst_n,
            clk_i           => CLK20_VCXO,
            led_intensity_i => c_LED_INTENSITY,
            led_state_i     => f_STD_LOGIC_VECTOR(s_led_state_array),
            column_o(0)     => LED_WR_OWNADDR_I2C,
            column_o(1)     => LED_WR_GMT_TTL_TTLN,
            column_o(2)     => LED_WR_LINK_SYSERROR,
            column_o(3)     => LED_WR_OK_SYSPW,
            column_o(4)     => LED_MULTICAST_2_0,
            column_o(5)     => LED_MULTICAST_3_1,
            line_o(0)       => LED_CTRL0,
            line_o(1)       => LED_CTRL1,
            line_oen_o(0)   => LED_CTRL0_OEN,
            line_oen_o(1)   => LED_CTRL1_OEN);

end Behavioral;


