DS_DMA
pcie_src/pcie_core64_m1/source_virtex6/pcie_upconfig_fix_3451_v6.vhd
00001 -------------------------------------------------------------------------------
00002 --
00003 -- (c) Copyright 2009-2011 Xilinx, Inc. All rights reserved.
00004 --
00005 -- This file contains confidential and proprietary information
00006 -- of Xilinx, Inc. and is protected under U.S. and
00007 -- international copyright and other intellectual property
00008 -- laws.
00009 --
00010 -- DISCLAIMER
00011 -- This disclaimer is not a license and does not grant any
00012 -- rights to the materials distributed herewith. Except as
00013 -- otherwise provided in a valid license issued to you by
00014 -- Xilinx, and to the maximum extent permitted by applicable
00015 -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
00016 -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
00017 -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
00018 -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
00019 -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
00020 -- (2) Xilinx shall not be liable (whether in contract or tort,
00021 -- including negligence, or under any other theory of
00022 -- liability) for any loss or damage of any kind or nature
00023 -- related to, arising under or in connection with these
00024 -- materials, including for any direct, or any indirect,
00025 -- special, incidental, or consequential loss or damage
00026 -- (including loss of data, profits, goodwill, or any type of
00027 -- loss or damage suffered as a result of any action brought
00028 -- by a third party) even if such damage or loss was
00029 -- reasonably foreseeable or Xilinx had been advised of the
00030 -- possibility of the same.
00031 --
00032 -- CRITICAL APPLICATIONS
00033 -- Xilinx products are not designed or intended to be fail-
00034 -- safe, or for use in any application requiring fail-safe
00035 -- performance, such as life-support or safety devices or
00036 -- systems, Class III medical devices, nuclear facilities,
00037 -- applications related to the deployment of airbags, or any
00038 -- other applications that could lead to death, personal
00039 -- injury, or severe property or environmental damage
00040 -- (individually and collectively, "Critical
00041 -- Applications"). Customer assumes the sole risk and
00042 -- liability of any use of Xilinx products in Critical
00043 -- Applications, subject only to applicable laws and
00044 -- regulations governing limitations on product liability.
00045 --
00046 -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
00047 -- PART OF THIS FILE AT ALL TIMES.
00048 --
00049 -------------------------------------------------------------------------------
00050 -- Project    : Virtex-6 Integrated Block for PCI Express
00051 -- File       : pcie_upconfig_fix_3451_v6.vhd
00052 -- Version    : 2.3
00053 ---- Description: Virtex6 Workaround for Root Port Upconfigurability Bug
00054 ----
00055 ----
00056 ----------------------------------------------------------------------------------
00057 
00058 library ieee;
00059    use ieee.std_logic_1164.all;
00060    use ieee.std_logic_unsigned.all;
00061 
00062 entity pcie_upconfig_fix_3451_v6 is
00063    generic (
00064       
00065       UPSTREAM_FACING                              : boolean := TRUE;
00066       PL_FAST_TRAIN                                : boolean := FALSE;
00067       LINK_CAP_MAX_LINK_WIDTH                      : bit_vector := X"08"
00068    );
00069    port (
00070       pipe_clk                                     : in std_logic;
00071       pl_phy_lnkup_n                               : in std_logic;
00072       pl_ltssm_state                               : in std_logic_vector(5 downto 0);
00073       pl_sel_lnk_rate                              : in std_logic;
00074       pl_directed_link_change                      : in std_logic_vector(1 downto 0);
00075       cfg_link_status_negotiated_width             : in std_logic_vector(3 downto 0);
00076       pipe_rx0_data                                : in std_logic_vector(15 downto 0);
00077       pipe_rx0_char_isk                            : in std_logic_vector(1 downto 0);
00078       filter_pipe                                  : out std_logic
00079    );
00080 end pcie_upconfig_fix_3451_v6;
00081 
00082 architecture v6_pcie of pcie_upconfig_fix_3451_v6 is
00083 
00084   -- purpose: perform bitwise and and check for value 
00085   function slv_check (
00086     val_in1   : std_logic_vector(7 downto 0);
00087     val_in2   : std_logic_vector(7 downto 0);
00088     val_check : std_logic_vector(7 downto 0))
00089     return std_logic is 
00090 
00091     variable val_bw : std_logic_vector(7 downto 0) := X"00";
00092   begin  -- slv_check
00093     for i in 7 downto 0 loop
00094       val_bw(i) := val_in1(i) and val_in2(i);
00095     end loop;  -- i
00096     if val_bw = val_check then
00097       return '1';
00098     else
00099       return '0';
00100     end if;
00101   end slv_check;
00102 
00103   FUNCTION to_stdlogic (
00104     in_val      : IN boolean) RETURN std_logic IS
00105   BEGIN
00106     IF (in_val) THEN
00107       RETURN('1');
00108     ELSE
00109       RETURN('0');
00110     END IF;
00111   END to_stdlogic;
00112 
00113 
00114    constant TCQ                                    : integer := 1;
00115    signal reg_filter_pipe                          : std_logic;
00116    
00117    signal reg_tsx_counter                          : std_logic_vector(15 downto 0);
00118    signal tsx_counter                              : std_logic_vector(15 downto 0);
00119    
00120    signal cap_link_width                           : std_logic_vector(5 downto 0);
00121 
00122    signal reg_filter_used                          : std_logic;
00123    signal reg_com_then_pad                         : std_logic;
00124    signal reg_data0_b4                             : std_logic;
00125    signal reg_data0_08                             : std_logic;
00126    signal reg_data0_43                             : std_logic;
00127    signal reg_data1_b4                             : std_logic;
00128    signal reg_data1_08                             : std_logic;
00129    signal reg_data1_43                             : std_logic;
00130    signal reg_data0_com                            : std_logic;
00131    signal reg_data1_com                            : std_logic;
00132    signal reg_data1_pad                            : std_logic;
00133 
00134    signal data0_b4                                 : std_logic;
00135    signal data0_08                                 : std_logic;
00136    signal data0_43                                 : std_logic;
00137 
00138    signal data1_b4                                 : std_logic;
00139    signal data1_08                                 : std_logic;
00140    signal data1_43                                 : std_logic;
00141 
00142    signal data0_com                                : std_logic;
00143    signal data0_pad                                : std_logic;
00144 
00145    signal data1_com                                : std_logic;
00146    signal data1_pad                                : std_logic;
00147 
00148    signal com_then_pad0                            : std_logic;
00149    signal com_then_pad1                            : std_logic;
00150    signal com_then_pad                             : std_logic;
00151    signal filter_used                              : std_logic;
00152    signal com_then_pad_reg                         : std_logic;
00153    signal filter_used_reg                          : std_logic;
00154 
00155    -- X-HDL generated signals
00156 
00157    signal v6pcie1                                  : std_logic_vector(15 downto 0);
00158    signal v6pcie2                                  : std_logic_vector(15 downto 0);
00159    
00160    -- Declare intermediate signals for referenced outputs
00161    signal filter_pipe_v6pcie0                      : std_logic;
00162 
00163 begin
00164    -- Drive referenced outputs
00165    filter_pipe <= filter_pipe_v6pcie0;
00166    
00167    -- Corrupting all Tsx on all lanes as soon as we do R.RC->R.RI transition to allow time for
00168    -- the core to see the TS1s on all the lanes being configured at the same time
00169    -- R.RI has a 2ms timeout.Corrupting tsxs for ~1/4 of that time
00170    -- 225 (00E1 Hex) pipe_clk cycles-sim_fast_train
00171    -- 60000 (EA60 Hex) pipe_clk cycles-without sim_fast_train
00172    -- Not taking any action  when PLDIRECTEDLINKCHANGE is set
00173    
00174    -- Detect xx, COM then PAD,xx or COM,PAD then PAD,xx
00175    -- data0 will be the first symbol on lane 0, data1 will be the next symbol.
00176    --  Don't look for PAD on data1 since it's unnecessary.
00177    -- COM=0xbc and PAD=0xf7 (and isk).
00178    -- detect if (data & 0xb4) == 0xb4 and isk, and then
00179    --  if (data & 0x4b) == 0x08 or 0x43.  This distinguishes COM and PAD, using
00180    --  no more than a 6-input LUT, so should be "free".
00181 
00182    data0_b4 <= pipe_rx0_char_isk(0) and slv_check(pipe_rx0_data(7 downto 0), X"b4", X"b4");
00183    data0_08 <= slv_check(pipe_rx0_data(7 downto 0), X"4b", X"08");
00184    data0_43 <= slv_check(pipe_rx0_data(7 downto 0), X"4b", X"43");
00185 
00186    data1_b4 <= pipe_rx0_char_isk(1) and slv_check(pipe_rx0_data(15 downto 8), X"b4", X"b4");
00187    data1_08 <= slv_check(pipe_rx0_data(15 downto 8), X"4b", X"08");
00188    data1_43 <= slv_check(pipe_rx0_data(15 downto 8), X"4b", X"43");
00189 
00190    data0_com <= reg_data0_b4 and reg_data0_08;
00191    data1_com <= reg_data1_b4 and reg_data1_08;
00192    data0_pad <= reg_data0_b4 and reg_data0_43;
00193    data1_pad <= reg_data1_b4 and reg_data1_43;
00194    com_then_pad0 <= reg_data0_com and reg_data1_pad and data0_pad;
00195    com_then_pad1 <= reg_data1_com and data0_pad and data1_pad;
00196    com_then_pad <= (com_then_pad0 or com_then_pad1) and not(reg_filter_used);
00197 
00198    filter_used <= to_stdlogic(pl_ltssm_state = "100000") and (reg_filter_pipe or reg_filter_used);
00199 
00200    com_then_pad_reg <= com_then_pad when ((not(pl_phy_lnkup_n)) = '1') else
00201                        '0';
00202    filter_used_reg <= filter_used when ((not(pl_phy_lnkup_n)) = '1') else
00203                       '0';
00204    process (pipe_clk)
00205    begin
00206       if (pipe_clk'event and pipe_clk = '1') then
00207          reg_data0_b4 <= data0_b4 after (TCQ)*1 ps;
00208          reg_data0_08 <= data0_08 after (TCQ)*1 ps;
00209          reg_data0_43 <= data0_43 after (TCQ)*1 ps;
00210          reg_data1_b4 <= data1_b4 after (TCQ)*1 ps;
00211          reg_data1_08 <= data1_08 after (TCQ)*1 ps;
00212          reg_data1_43 <= data1_43 after (TCQ)*1 ps;
00213          reg_data0_com <= data0_com after (TCQ)*1 ps;
00214          reg_data1_com <= data1_com after (TCQ)*1 ps;
00215          reg_data1_pad <= data1_pad after (TCQ)*1 ps;
00216          reg_com_then_pad <= com_then_pad_reg after (TCQ)*1 ps;
00217          
00218          reg_filter_used <= filter_used_reg after (TCQ)*1 ps;
00219       end if;
00220    end process;
00221    
00222    v6pcie1 <= X"0320" when (pl_sel_lnk_rate = '1') else
00223               X"0190";
00224    v6pcie2 <= X"00E1" when (PL_FAST_TRAIN) else
00225               v6pcie1;
00226 
00227    process (pipe_clk)
00228    begin
00229       if (pipe_clk'event and pipe_clk = '1') then
00230 
00231         if (pl_phy_lnkup_n = '1') then
00232 
00233           reg_tsx_counter <= "0000000000000000" after (TCQ)*1 ps;
00234           reg_filter_pipe <= '0' after (TCQ)*1 ps;
00235 
00236         elsif ((pl_ltssm_state = "100000") and (reg_com_then_pad = '1') and (("00" & cfg_link_status_negotiated_width) /= cap_link_width(5 downto 0)) and (pl_directed_link_change(1 downto 0) = "00")) then
00237 
00238           reg_tsx_counter <= "0000000000000000" after (TCQ)*1 ps;
00239           reg_filter_pipe <= '1' after (TCQ)*1 ps;
00240 
00241         elsif (filter_pipe_v6pcie0 = '1') then 
00242 
00243           if (tsx_counter < v6pcie2) then
00244                
00245             reg_tsx_counter <= tsx_counter + "0000000000000001" after (TCQ)*1 ps;
00246             reg_filter_pipe <= '1' after (TCQ)*1 ps;
00247 
00248           else
00249                
00250             reg_tsx_counter <= "0000000000000000" after (TCQ)*1 ps;
00251             reg_filter_pipe <= '0' after (TCQ)*1 ps;
00252 
00253           end if;
00254         end if;
00255       end if;
00256    end process;
00257    
00258    
00259    filter_pipe_v6pcie0 <= '0' when (UPSTREAM_FACING) else
00260                           reg_filter_pipe;
00261    tsx_counter <= reg_tsx_counter;
00262    
00263    cap_link_width <= to_stdlogicvector(LINK_CAP_MAX_LINK_WIDTH);
00264    
00265 end v6_pcie;
00266 
00267