diff --git a/libraries/technology/transceiver/tech_transceiver_arria10_1.vhd b/libraries/technology/transceiver/tech_transceiver_arria10_1.vhd new file mode 100644 index 0000000000000000000000000000000000000000..69164cc5ad9a6e188257202d2f7b2f4804988904 --- /dev/null +++ b/libraries/technology/transceiver/tech_transceiver_arria10_1.vhd @@ -0,0 +1,233 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + + +entity tech_transceiver_arria10_1 is + generic ( + g_nof_channels : natural := 1 + ); + port ( + clk : in std_logic; + reset_p : in std_logic; + refclk : in std_logic; + clk_156_arr : out std_logic_vector(g_nof_channels-1 downto 0); + clk_312_arr : out std_logic_vector(g_nof_channels-1 downto 0); + tx_serial_data : out std_logic_vector(g_nof_channels-1 downto 0); + rx_serial_data : in std_logic_vector(g_nof_channels-1 downto 0); + tx_parallel_data : in std_logic_vector(64*g_nof_channels-1 downto 0); + rx_parallel_data : out std_logic_vector(64*g_nof_channels-1 downto 0); + tx_control : in std_logic_vector(8*g_nof_channels-1 downto 0); + rx_control : out std_logic_vector(8*g_nof_channels-1 downto 0) + ); + end tech_transceiver_arria10_1; + + +architecture str of tech_transceiver_arria10_1 is + + component transceiver_phy_1 is + port ( + tx_analogreset : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + tx_digitalreset : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + rx_analogreset : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + rx_digitalreset : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + tx_cal_busy : out std_logic_vector(g_nof_channels-1 downto 0); + rx_cal_busy : out std_logic_vector(g_nof_channels-1 downto 0); + rx_is_lockedtodata : out std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + tx_serial_clk0 : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + rx_cdr_refclk0 : in std_logic := 'X'; + tx_serial_data : out std_logic_vector(g_nof_channels-1 downto 0); + rx_serial_data : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + tx_coreclkin : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + rx_coreclkin : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + tx_clkout : out std_logic_vector(g_nof_channels-1 downto 0); + rx_clkout : out std_logic_vector(g_nof_channels-1 downto 0); + tx_pma_clkout : out std_logic_vector(g_nof_channels-1 downto 0); + tx_pma_div_clkout : out std_logic_vector(g_nof_channels-1 downto 0); + tx_enh_data_valid : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + rx_enh_data_valid : out std_logic_vector(g_nof_channels-1 downto 0); + rx_enh_blk_lock : out std_logic_vector(g_nof_channels-1 downto 0); + tx_parallel_data : in std_logic_vector(64*g_nof_channels-1 downto 0) := (others => 'X'); + tx_control : in std_logic_vector(8*g_nof_channels-1 downto 0) := (others => 'X'); + tx_err_ins : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + unused_tx_parallel_data : in std_logic_vector(64*g_nof_channels-1 downto 0) := (others => 'X'); + unused_tx_control : in std_logic_vector(9*g_nof_channels-1 downto 0) := (others => 'X'); + rx_parallel_data : out std_logic_vector(64*g_nof_channels-1 downto 0); + rx_control : out std_logic_vector(8*g_nof_channels-1 downto 0); + unused_rx_parallel_data : out std_logic_vector(64*g_nof_channels-1 downto 0); + unused_rx_control : out std_logic_vector(12*g_nof_channels-1 downto 0) + ); + end component transceiver_phy_1; + + component transceiver_reset_controller_1 is + port ( + clock : in std_logic := 'X'; + reset : in std_logic := 'X'; + pll_powerdown : out std_logic_vector(0 downto 0); + tx_analogreset : out std_logic_vector(g_nof_channels-1 downto 0); + tx_digitalreset : out std_logic_vector(g_nof_channels-1 downto 0); + tx_ready : out std_logic_vector(g_nof_channels-1 downto 0); + pll_locked : in std_logic_vector(0 downto 0) := (others => 'X'); + pll_select : in std_logic_vector(0 downto 0) := (others => 'X'); + tx_cal_busy : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + rx_analogreset : out std_logic_vector(g_nof_channels-1 downto 0); + rx_digitalreset : out std_logic_vector(g_nof_channels-1 downto 0); + rx_ready : out std_logic_vector(g_nof_channels-1 downto 0); + rx_is_lockedtodata : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X'); + rx_cal_busy : in std_logic_vector(g_nof_channels-1 downto 0) := (others => 'X') + ); + end component transceiver_reset_controller_1; + + component transceiver_pll is + port ( + pll_powerdown : in std_logic := 'X'; + pll_refclk0 : in std_logic := 'X'; -- clk + pll_locked : out std_logic; -- pll_locked + pll_cal_busy : out std_logic; + mcgb_rst : in std_logic := 'X'; -- mcgb_rst + mcgb_serial_clk : out std_logic -- clk + ); + end component transceiver_pll; + + component pll_xgmii_mac_clocks is + port ( + pll_refclk0 : in std_logic := 'X'; -- clk + pll_powerdown : in std_logic := 'X'; -- pll_powerdown + pll_locked : out std_logic; -- pll_locked + outclk0 : out std_logic; -- clk + pll_cal_busy : out std_logic; -- pll_cal_busy + outclk1 : out std_logic -- clk + ); + end component pll_xgmii_mac_clocks; + + + -- signals for the transceivers + signal tx_data_valid : std_logic_vector(g_nof_channels-1 downto 0) := (others => '1'); + signal tx_clk : std_logic_vector(g_nof_channels-1 downto 0); + signal rx_clk : std_logic_vector(g_nof_channels-1 downto 0); + signal tx_analogreset : std_logic_vector(g_nof_channels-1 downto 0); + signal tx_digitalreset : std_logic_vector(g_nof_channels-1 downto 0); + signal rx_analogreset : std_logic_vector(g_nof_channels-1 downto 0); + signal rx_digitalreset : std_logic_vector(g_nof_channels-1 downto 0); + signal tx_cal_busy : std_logic_vector(g_nof_channels-1 downto 0); + signal rx_cal_busy : std_logic_vector(g_nof_channels-1 downto 0); + signal txpll_cal_busy : std_logic_vector(g_nof_channels-1 downto 0); + signal pll_cal_busy : std_logic; + signal rx_is_lockedtodata: std_logic_vector(g_nof_channels-1 downto 0); + signal pll_powerdown : std_logic_vector(0 downto 0); + signal pll_locked : std_logic_vector(0 downto 0); + signal tx_serial_clk : std_logic_vector(g_nof_channels-1 downto 0); + signal mcgb_serial_clk : std_logic; + + signal tx_pma_clkout : std_logic_vector(g_nof_channels-1 downto 0); + signal tx_pma_div_clkout : std_logic_vector(g_nof_channels-1 downto 0); + signal rx_pma_clkout : std_logic_vector(g_nof_channels-1 downto 0); + signal rx_pma_div_clkout : std_logic_vector(g_nof_channels-1 downto 0); + signal clk_156_internal : std_logic_vector(g_nof_channels-1 downto 0); + signal clk_312_internal : std_logic_vector(g_nof_channels-1 downto 0); + +begin + + + clk_156_arr <= clk_156_internal; + clk_312_arr <= clk_312_internal; + + transceiver_phy : transceiver_phy_1 + port map ( + tx_analogreset => tx_analogreset, + tx_digitalreset => tx_digitalreset, + rx_analogreset => rx_analogreset, + rx_digitalreset => rx_digitalreset, + tx_cal_busy => tx_cal_busy, + rx_cal_busy => rx_cal_busy, + rx_is_lockedtodata => rx_is_lockedtodata, + tx_serial_clk0 => tx_serial_clk, + rx_cdr_refclk0 => refclk, + tx_serial_data => tx_serial_data, + rx_serial_data => rx_serial_data, + tx_coreclkin => clk_156_internal, -- write side clock for tx fifo + rx_coreclkin => clk_156_internal, -- read side clock for rx fifo + tx_clkout => tx_clk, + rx_clkout => rx_clk, + tx_pma_clkout => tx_pma_clkout, + tx_pma_div_clkout => tx_pma_div_clkout, + tx_enh_data_valid => tx_data_valid, + rx_enh_data_valid => open, + rx_enh_blk_lock => open, + tx_parallel_data => tx_parallel_data, + tx_control => tx_control, + tx_err_ins => (others => '0'), -- use to insert sync errors + unused_tx_parallel_data => (others => '0'), + unused_tx_control => (others => '0'), + rx_parallel_data => rx_parallel_data, + rx_control => rx_control, + unused_rx_parallel_data => open, + unused_rx_control => open + ); + + transceiver_reset : transceiver_reset_controller_1 + port map ( + clock => clk, + reset => reset_p, + pll_powerdown => pll_powerdown, + tx_analogreset => tx_analogreset, + tx_digitalreset => tx_digitalreset, + tx_ready => open, + pll_locked => pll_locked, + pll_select => "0", + tx_cal_busy => txpll_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 + ); + + transceiver_pll_front : transceiver_pll + port map ( + pll_powerdown => pll_powerdown(0), + pll_refclk0 => refclk, + pll_locked => pll_locked(0), + pll_cal_busy => pll_cal_busy, + mcgb_rst => pll_powerdown(0), + mcgb_serial_clk => mcgb_serial_clk + ); + + u_pll_xgmii_mac_clocks : component pll_xgmii_mac_clocks + port map ( + pll_refclk0 => refclk, -- pll_refclk0.clk + pll_powerdown => reset_p, -- pll_powerdown.pll_powerdown + pll_locked => open, -- pll_locked.pll_locked + outclk0 => clk_156_internal(0), -- outclk0.clk + pll_cal_busy => open, -- pll_cal_busy.pll_cal_busy + outclk1 => clk_312_internal(0) -- outclk1.clk + ); + + + tx_serial_clk <= (others => mcgb_serial_clk); + txpll_cal_busy <= tx_cal_busy when pll_cal_busy = '0' else (others => '1'); + +end;