library ieee;
	use ieee.std_logic_1164.all;
	use ieee.numeric_std.all;
	
	
entity multi_5 is		
	port (
		clk_clk                    : in    std_logic                     := 'X';             -- clk (system/core)
		clk_pll                    : in    std_logic_vector(0 downto 0)  := (others => '0'); -- clk (clk HSMC 100MHz diff-volt)
		rst	                     : in    std_logic                     := 'X';             -- rst
	   rx_serial_data     		   : in	  std_logic_vector(4 downto 0)  := (others => '0'); -- serial data in
		tx_serial_data     			: out	  std_logic_vector(4 downto 0)							 -- serial data out		
	);
end entity multi_5;


architecture arch of multi_5 is

	component nPhyCV is
		port (
			pll_powerdown      : in  std_logic_vector(4 downto 0)   := (others => '0'); --      pll_powerdown.pll_powerdown
			tx_analogreset     : in  std_logic_vector(4 downto 0)   := (others => '0'); --     tx_analogreset.tx_analogreset
			tx_digitalreset    : in  std_logic_vector(4 downto 0)   := (others => '0'); --    tx_digitalreset.tx_digitalreset
			tx_pll_refclk      : in  std_logic_vector(0 downto 0)   := (others => '0'); --      tx_pll_refclk.tx_pll_refclk
			tx_serial_data     : out std_logic_vector(4 downto 0);                      --     tx_serial_data.tx_serial_data
			pll_locked         : out std_logic_vector(4 downto 0);                      --         pll_locked.pll_locked
			rx_analogreset     : in  std_logic_vector(4 downto 0)   := (others => '0'); --     rx_analogreset.rx_analogreset
			rx_digitalreset    : in  std_logic_vector(4 downto 0)   := (others => '0'); --    rx_digitalreset.rx_digitalreset
			rx_cdr_refclk      : in  std_logic_vector(0 downto 0)   := (others => '0'); --      rx_cdr_refclk.rx_cdr_refclk
			rx_serial_data     : in  std_logic_vector(4 downto 0)   := (others => '0'); --     rx_serial_data.rx_serial_data
			rx_is_lockedtodata : out std_logic_vector(4 downto 0);                      -- rx_is_lockedtodata.rx_is_lockedtodata
			tx_parallel_data   : in  std_logic_vector(219 downto 0) := (others => '0'); --   tx_parallel_data.tx_parallel_data
			rx_parallel_data   : out std_logic_vector(319 downto 0);                    --   rx_parallel_data.rx_parallel_data
			tx_std_coreclkin   : in  std_logic_vector(4 downto 0)   := (others => '0'); --   tx_std_coreclkin.tx_std_coreclkin
			rx_std_coreclkin   : in  std_logic_vector(4 downto 0)   := (others => '0'); --   rx_std_coreclkin.rx_std_coreclkin
			tx_std_clkout      : out std_logic_vector(4 downto 0);                      --      tx_std_clkout.tx_std_clkout
			rx_std_clkout      : out std_logic_vector(4 downto 0);                      --      rx_std_clkout.rx_std_clkout
			tx_cal_busy        : out std_logic_vector(4 downto 0);                      --        tx_cal_busy.tx_cal_busy
			rx_cal_busy        : out std_logic_vector(4 downto 0);                      --        rx_cal_busy.rx_cal_busy
			reconfig_to_xcvr   : in  std_logic_vector(699 downto 0) := (others => '0'); --   reconfig_to_xcvr.reconfig_to_xcvr
			reconfig_from_xcvr : out std_logic_vector(459 downto 0)                     -- reconfig_from_xcvr.reconfig_from_xcvr
		);
	end component nPhyCV;
	
	component nPhyReconf is
		port (
			reconfig_busy             : out std_logic;                                         --      reconfig_busy.reconfig_busy
			mgmt_clk_clk              : in  std_logic                      := '0';             --       mgmt_clk_clk.clk
			mgmt_rst_reset            : in  std_logic                      := '0';             --     mgmt_rst_reset.reset
			reconfig_mgmt_address     : in  std_logic_vector(6 downto 0)   := (others => '0'); --      reconfig_mgmt.address
			reconfig_mgmt_read        : in  std_logic                      := '0';             --                   .read
			reconfig_mgmt_readdata    : out std_logic_vector(31 downto 0);                     --                   .readdata
			reconfig_mgmt_waitrequest : out std_logic;                                         --                   .waitrequest
			reconfig_mgmt_write       : in  std_logic                      := '0';             --                   .write
			reconfig_mgmt_writedata   : in  std_logic_vector(31 downto 0)  := (others => '0'); --                   .writedata
			reconfig_to_xcvr          : out std_logic_vector(699 downto 0);                    --   reconfig_to_xcvr.reconfig_to_xcvr
			reconfig_from_xcvr        : in  std_logic_vector(459 downto 0) := (others => '0')  -- reconfig_from_xcvr.reconfig_from_xcvr
		);
	end component nPhyReconf;
	
	component nPhyRstCtrl is
		port (
			clock              : in  std_logic                    := '0';             --              clock.clk
			reset              : in  std_logic                    := '0';             --              reset.reset
			pll_powerdown      : out std_logic_vector(4 downto 0);                    --      pll_powerdown.pll_powerdown
			tx_analogreset     : out std_logic_vector(4 downto 0);                    --     tx_analogreset.tx_analogreset
			tx_digitalreset    : out std_logic_vector(4 downto 0);                    --    tx_digitalreset.tx_digitalreset
			tx_ready           : out std_logic_vector(4 downto 0);                    --           tx_ready.tx_ready
			pll_locked         : in  std_logic_vector(4 downto 0) := (others => '0'); --         pll_locked.pll_locked
			pll_select         : in  std_logic_vector(2 downto 0) := (others => '0'); --         pll_select.pll_select
			tx_cal_busy        : in  std_logic_vector(4 downto 0) := (others => '0'); --        tx_cal_busy.tx_cal_busy
			rx_analogreset     : out std_logic_vector(4 downto 0);                    --     rx_analogreset.rx_analogreset
			rx_digitalreset    : out std_logic_vector(4 downto 0);                    --    rx_digitalreset.rx_digitalreset
			rx_ready           : out std_logic_vector(4 downto 0);                    --           rx_ready.rx_ready
			rx_is_lockedtodata : in  std_logic_vector(4 downto 0) := (others => '0'); -- rx_is_lockedtodata.rx_is_lockedtodata
			rx_cal_busy        : in  std_logic_vector(4 downto 0) := (others => '0')  --        rx_cal_busy.rx_cal_busy
		);
	end component nPhyRstCtrl;
	
	signal tx_parallel_data   : std_logic_vector(219 downto 0) := (others => '0');
	signal rx_parallel_data   : std_logic_vector(319 downto 0) := (others => '0');
	signal tx_std_clkout      : std_logic_vector(4 downto 0)  := (others => '0');
	signal rx_std_clkout      : std_logic_vector(4 downto 0)  := (others => '0');
	signal rx_is_lockedtodata : std_logic_vector(4 downto 0) := (others => '0');
	signal tx_cal_busy		  : std_logic_vector(4 downto 0) := (others => '0');
	signal rx_cal_busy		  : std_logic_vector(4 downto 0) := (others => '0');
	signal reconfig_to_xcvr	  : std_logic_vector(699 downto 0) := (others => '0');
	signal reconfig_from_xcvr : std_logic_vector(459 downto 0) := (others => '0');
	signal tx_analogreset	  : std_logic_vector(4 downto 0) := (others => '0');
	signal tx_digitalreset	  : std_logic_vector(4 downto 0) := (others => '0');
	signal rx_analogreset	  : std_logic_vector(4 downto 0) := (others => '0');
	signal rx_digitalreset	  : std_logic_vector(4 downto 0) := (others => '0');
	signal pll_locked			  : std_logic_vector(4 downto 0) := (others => '0');
	signal pll_powerdown		  : std_logic_vector(4 downto 0) := (others => '0');

begin

	
	
	-- PHY Interface
	u0 : component nPhyCV
		port map (
			pll_powerdown      		=> pll_powerdown		,
			tx_analogreset     		=> tx_analogreset    ,
			tx_digitalreset    		=> tx_digitalreset   ,
			tx_pll_refclk      		=> clk_pll     		,
			tx_serial_data     		=> tx_serial_data    ,
			pll_locked         		=> pll_locked    		,
			rx_analogreset     		=> rx_analogreset    ,
			rx_digitalreset    		=> rx_digitalreset	,
			rx_cdr_refclk      		=> clk_pll     		,
			rx_serial_data     		=> rx_serial_data    ,
			tx_parallel_data   		=> tx_parallel_data  ,
			rx_parallel_data   		=> rx_parallel_data  ,
			rx_is_lockedtodata 		=> rx_is_lockedtodata,
			tx_std_coreclkin   		=> clk_clk & clk_clk & clk_clk & clk_clk & clk_clk	,
			rx_std_coreclkin   		=> clk_clk & clk_clk & clk_clk & clk_clk & clk_clk	,
			tx_std_clkout      		=> tx_std_clkout     ,
			rx_std_clkout      		=> rx_std_clkout     ,
			tx_cal_busy        		=> tx_cal_busy			,
			rx_cal_busy        		=> rx_cal_busy			,
			reconfig_to_xcvr   		=> reconfig_to_xcvr	,
			reconfig_from_xcvr 		=> reconfig_from_xcvr
		);
		
		-- Reconfig Controller
	u1 : component nPhyReconf
		port map (
			reconfig_busy             => open,
			mgmt_clk_clk              => clk_clk,
			mgmt_rst_reset            => rst,
			reconfig_mgmt_address     => (others => '0'),
			reconfig_mgmt_read        => '0',
			reconfig_mgmt_readdata    => open,
			reconfig_mgmt_waitrequest => open,
			reconfig_mgmt_write       => open,
			reconfig_mgmt_writedata   => (others => '0'),
			reconfig_to_xcvr          => reconfig_to_xcvr,
			reconfig_from_xcvr        => reconfig_from_xcvr
		);
	
	-- RESET Controller
	u2 : component nPhyRstCtrl
		port map (
			clock                     => clk_clk,
			reset                     => rst,
			pll_powerdown             => pll_powerdown,
			tx_analogreset            => tx_analogreset,
			tx_digitalreset           => tx_digitalreset,
			tx_ready                  => open,
			pll_locked                => pll_locked,
			pll_select                => "000",
			tx_cal_busy               => tx_cal_busy,
			rx_analogreset            => rx_analogreset,
			rx_digitalreset           => rx_digitalreset,
			rx_ready                  => open,
			rx_is_lockedtodata        => rx_is_lockedtodata,
			rx_cal_busy               => rx_cal_busy
		);
		
		
	process (clk_clk) begin
	if rising_edge(clk_clk) then
		if rst = '1' then
			tx_parallel_data	<= (others => '0');
		else
			tx_parallel_data	<= (others => '1');
		end if;		
	end if;
	end process;
	
end architecture arch;