From b134c3c96c558ef13a8873a819ee8674dbbea15e Mon Sep 17 00:00:00 2001
From: Jonathan Hargreaves <hargreaves@astron.nl>
Date: Mon, 26 Jan 2015 13:12:40 +0000
Subject: [PATCH] arria 10 transceiver with pll to generate xgmii clocks

---
 .../tech_transceiver_arria10_1.vhd            | 233 ++++++++++++++++++
 1 file changed, 233 insertions(+)
 create mode 100644 libraries/technology/transceiver/tech_transceiver_arria10_1.vhd

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 0000000000..69164cc5ad
--- /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;
-- 
GitLab