--
-- tms_top.vhd
--
-- Top Level User Application for TMS PUPE System
--
--
-- Version 1.0 30/1/06 A.McCormick (Alpha Data)



library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;

library work;
use work.common_interface.all;
use work.version.all;

library unisim;
use unisim.vcomponents.all;

entity user_top_level is
  
  port (
    -- Host Abstract Interface Connection
    clk        : in  std_logic;
    rst        : in  std_logic;
    system_in  : in  std_logic_vector(system_width-1 downto 0);
    system_out : out std_logic_vector(system_width-1 downto 0);
    -- Timing Inputs
    tbus_bplane	:inout std_logic_vector(10 downto 1);
    tbus_header	:inout std_logic_vector(10 downto 1);  
    tbus_master	:in std_logic_vector(10 downto 1);
    ten_mhz_clk       : in std_logic;
    -- IO Output
    phase_table_msb_out : out std_logic_vector(2 downto 0);
    -- ADC Inputs
    adc_in_0_0 : in std_logic_vector(13 downto 0);
    adc_in_0_1 : in std_logic_vector(13 downto 0);
    adc_in_0_2 : in std_logic_vector(13 downto 0);
    adc_in_1_0 : in std_logic_vector(13 downto 0);
    adc_in_1_1 : in std_logic_vector(13 downto 0);
    adc_in_1_2 : in std_logic_vector(13 downto 0);
    adc_in_2_0 : in std_logic_vector(13 downto 0);
    adc_in_2_1 : in std_logic_vector(13 downto 0);
    adc_in_2_2 : in std_logic_vector(13 downto 0);
    adc_enb    : out std_logic_vector(2 downto 0);
    syn_rst    : out std_logic;
    user_leds  : out std_logic_vector(1 downto 0);
    debug      : in  std_Logic_vector(63 downto 0));

end user_top_level;

architecture rtl of user_top_level is

  constant no_of_pupes : integer := 3;
  
  
  component adc_ctrl
    port (
      clk         : in  std_logic;
      rst         : in  std_logic;
      system_in   : in  std_logic_vector(system_width-1 downto 0);
      system_out  : out std_logic_vector(system_width-1 downto 0);
      adc_in_0_0  : in  std_logic_vector(13 downto 0);
      adc_in_0_1  : in  std_logic_vector(13 downto 0);
      adc_in_0_2  : in  std_logic_vector(13 downto 0);
      adc_in_1_0  : in  std_logic_vector(13 downto 0);
      adc_in_1_1  : in  std_logic_vector(13 downto 0);
      adc_in_1_2  : in  std_logic_vector(13 downto 0);
      adc_in_2_0  : in  std_logic_vector(13 downto 0);
      adc_in_2_1  : in  std_logic_vector(13 downto 0);
      adc_in_2_2  : in  std_logic_vector(13 downto 0);
      adc_out_0_0 : out std_logic_vector(13 downto 0);
      adc_out_0_1 : out std_logic_vector(13 downto 0);
      adc_out_0_2 : out std_logic_vector(13 downto 0);
      adc_out_1_0 : out std_logic_vector(13 downto 0);
      adc_out_1_1 : out std_logic_vector(13 downto 0);
      adc_out_1_2 : out std_logic_vector(13 downto 0);
      adc_out_2_0 : out std_logic_vector(13 downto 0);
      adc_out_2_1 : out std_logic_vector(13 downto 0);
      adc_out_2_2 : out std_logic_vector(13 downto 0);
      adc_enb    : out std_logic_vector(2 downto 0);
      syn_rst    : out std_logic;
      fref_test   : out std_logic;
      user_leds  : out std_logic_vector(1 downto 0));
  end component;

  component timing_io
    port (
      clk             : in  std_logic;
      rst             : in  std_logic;
      system_in       : in  std_logic_vector(system_width-1 downto 0);
      system_out      : out std_logic_vector(system_width-1 downto 0);
      ten_mhz_clk     : in  std_logic;
      tbus_bplane     : inout std_logic_vector(10 downto 1);
      tbus_header     : inout std_logic_vector(10 downto 1);  
      tbus_master     : in std_logic_vector(10 downto 1);
      ten_mhz_clk_out : out std_logic;
      cycle_start_out : out std_logic;
      cycle_stop_out  : out std_logic;
      cal_start_out   : out std_logic;
      cal_stop_out    : out std_logic;
      injection_out   : out std_logic;
      hchange_out     : out std_logic;
      fref_out        : out std_logic);
  end component;

  component pupe
    generic (
      index : integer := 0);
    port (
      -- Host Abstract Interface Connection
      clk         : in  std_logic;
      rst         : in  std_logic;
      system_in   : in  std_logic_vector(system_width-1 downto 0);
      system_out  : out std_logic_vector(system_width-1 downto 0);
      debug       : in  std_Logic_vector(63 downto 0);
      -- Interrupts
      irq         : out std_logic_vector(7 downto 0);
      -- IO Output
      phase_table_msb_out : out std_logic;
      -- Timing Inputs
      cycle_start : in  std_logic;
      cycle_stop  : in  std_logic;
      cal_start   : in  std_logic;
      cal_stop    : in  std_logic;
      injection   : in  std_logic;
      hchange     : in  std_logic;
      fref        : in  std_logic;
      fref_test         : in  std_logic;
      ten_mhz_clk : in  std_logic;
      -- Cross connections to other pupes plls
      pll_mixed_sigma0_out : out std_logic_vector(13 downto 0);
      pll_mixed_sigma1_out : out std_logic_vector(13 downto 0);
      pll_mixed_sigma0a_in : in std_logic_vector(13 downto 0);
      pll_mixed_sigma1a_in : in std_logic_vector(13 downto 0);
      pll_mixed_sigma0b_in : in std_logic_vector(13 downto 0);
      pll_mixed_sigma1b_in : in std_logic_vector(13 downto 0);  
      -- ADC Inputs     
      sigma       : in  std_logic_vector(13 downto 0);
      deltax      : in  std_logic_vector(13 downto 0);
      deltay      : in  std_logic_vector(13 downto 0));
  end component;




  -- Real Signals
  constant ncomponents : integer := 7;
  type     sys_bus_type is array (0 to ncomponents) of std_logic_vector(system_width-1 downto 0);
  signal s : sys_bus_type;
  signal s_tmp : std_logic_vector(system_width-1 downto 0);
  
  signal cycle_start_i : std_logic;
  signal cycle_stop_i  : std_logic;
  signal cal_start_i   : std_logic;
  signal cal_stop_i    : std_logic;
  signal injection_i   : std_logic;
  signal hchange_i     : std_logic;
  signal fref_i        : std_logic;
  signal ten_mhz_clk_i : std_logic;

  type adc_array is array (0 to 2) of std_logic_vector(13 downto 0);
  signal adc_out_0,adc_out_1,adc_out_2 : adc_array;

  type irq_array is array (0 to 2) of std_logic_vector(7 downto 0);
  signal irqs : irq_array;
  signal irq_signals : std_logic_vector(31 downto 0);
  signal status : std_logic_vector(31 downto 0);

  signal fref_test : std_logic;

  signal pll_mixed_sigma0_out, pll_mixed_sigma1_out, pll_mixed_sigma0a_in, pll_mixed_sigma1a_in, pll_mixed_sigma0b_in, pll_mixed_sigma1b_in  : adc_array;

  

  
begin  -- rtl

  s(0) <= system_in;

  tio0 : timing_io
    port map (
      clk             => clk,
      rst             => rst,
      system_in       => s(0),
      system_out      => s(1),
      ten_mhz_clk     => ten_mhz_clk,
      tbus_bplane     => tbus_bplane,
      tbus_header     => tbus_header,
      tbus_master     => tbus_master, 
      ten_mhz_clk_out => ten_mhz_clk_i,
      cycle_start_out => cycle_start_i,
      cycle_stop_out  => cycle_stop_i,
      cal_start_out   => cal_start_i,
      cal_stop_out    => cal_stop_i,
      injection_out   => injection_i,
      hchange_out     => hchange_i,
      fref_out        => fref_i);

  
  
  
 

  adc_ctrl0 : adc_ctrl
    port map (
      clk         => clk,
      rst         => rst,
      system_in   => s(1),
      system_out  => s(2),
      adc_in_0_0  => adc_in_0_0,
      adc_in_0_1  => adc_in_0_1,
      adc_in_0_2  => adc_in_0_2,
      adc_in_1_0  => adc_in_1_0,
      adc_in_1_1  => adc_in_1_1,
      adc_in_1_2  => adc_in_1_2,
      adc_in_2_0  => adc_in_2_0,
      adc_in_2_1  => adc_in_2_1,
      adc_in_2_2  => adc_in_2_2,
      adc_out_0_0 => adc_out_0(0),
      adc_out_0_1 => adc_out_1(0),
      adc_out_0_2 => adc_out_2(0),
      adc_out_1_0 => adc_out_0(1),
      adc_out_1_1 => adc_out_1(1),
      adc_out_1_2 => adc_out_2(1),
      adc_out_2_0 => adc_out_0(2),
      adc_out_2_1 => adc_out_1(2),
      adc_out_2_2 => adc_out_2(2),
      adc_enb => adc_enb,
      syn_rst => syn_rst,
      fref_test   => fref_test,
      user_leds => user_leds); 

  
  gen_pupes: for i in 0 to no_of_pupes-1 generate
    pupe_i: pupe
      generic map (
        index => i)
      port map (
        clk         => clk,
        rst         => rst,
        system_in   => s(i+2),
        system_out  => s(i+3),
        debug       => debug,
        irq         => irqs(i),
        phase_table_msb_out => phase_table_msb_out(i),
        cycle_start => cycle_start_i,
        cycle_stop  => cycle_stop_i,
        cal_start   => cal_start_i,
        cal_stop    => cal_stop_i,
        hchange     => hchange_i,
        injection   => injection_i,
        fref        => fref_i,
        fref_test   => fref_test,
        ten_mhz_clk => ten_mhz_clk_i,           
        pll_mixed_sigma0_out  => pll_mixed_sigma0_out(i),   
        pll_mixed_sigma1_out  => pll_mixed_sigma1_out(i),   
        pll_mixed_sigma0a_in  => pll_mixed_sigma0a_in(i),   
        pll_mixed_sigma1a_in  => pll_mixed_sigma1a_in(i),   
        pll_mixed_sigma0b_in  => pll_mixed_sigma0b_in(i),   
        pll_mixed_sigma1b_in  => pll_mixed_sigma1b_in(i),   
        sigma       => adc_out_0(i),
        deltax      => adc_out_1(i),
        deltay      => adc_out_2(i));   
  end generate gen_pupes;

  -- Cross-map PLL Mixed Sigmas
  pll_mixed_sigma0a_in(0) <= pll_mixed_sigma0_out(1);
  pll_mixed_sigma0b_in(0) <= pll_mixed_sigma0_out(2);
  pll_mixed_sigma0a_in(1) <= pll_mixed_sigma0_out(0);
  pll_mixed_sigma0b_in(1) <= pll_mixed_sigma0_out(2);
  pll_mixed_sigma0a_in(2) <= pll_mixed_sigma0_out(0);
  pll_mixed_sigma0b_in(2) <= pll_mixed_sigma0_out(1);
  pll_mixed_sigma1a_in(0) <= pll_mixed_sigma1_out(1);
  pll_mixed_sigma1b_in(0) <= pll_mixed_sigma1_out(2);
  pll_mixed_sigma1a_in(1) <= pll_mixed_sigma1_out(0);
  pll_mixed_sigma1b_in(1) <= pll_mixed_sigma1_out(2);
  pll_mixed_sigma1a_in(2) <= pll_mixed_sigma1_out(0);
  pll_mixed_sigma1b_in(2) <= pll_mixed_sigma1_out(1);
  
  s_tmp <= s(no_of_pupes+2);
    
  -- Firmware ID
  sreg0 : status_register
    generic map (
      width => 32, addr => 0)
    port map (
      clk         => clk, rst => rst, system_in => s_tmp, system_out => s(6),
      status_data => status);
 
  status <= X"43" & CONV_STD_LOGIC_VECTOR(version_major,8) & CONV_STD_LOGIC_VECTOR(version_minor,8) & CONV_STD_LOGIC_VECTOR(version_sub,8);

  -- IRQ Register
  ireg0: interrupt_register
    generic map (
      width => 32)
    port map (
      clk => clk,
      rst => rst,
      system_in => s(6),
      system_out => s(7),
      interrupt_enable => open,
      interrupt_trigger => irq_signals );

  irq_signals <= EXT( irqs(2) & irqs(1) & irqs(0) , 32);

  system_out <= s(7);



  
  
end rtl;
