DS_DMA
pcie_src/pcie_core64_m1/source_virtex6/axi_basic_rx_pipeline.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       : axi_basic_rx_pipeline.vhd
00052 -- Version    : 2.3
00053 --
00054 -- Description:
00055 --  TRN to AXI RX pipeline. Converts received data from TRN protocol to AXI.
00056 --
00057 --  Notes:
00058 --  Optional notes section.
00059 --
00060 --  Hierarchical:
00061 --    axi_basic_top
00062 --      axi_basic_rx
00063 --        axi_basic_rx_pipeline
00064 --
00065 -------------------------------------------------------------------------------
00066 -- Library Declarations
00067 --------------------------------------------------------------------------------
00068 
00069 LIBRARY ieee;
00070    USE ieee.std_logic_1164.all;
00071    USE ieee.std_logic_unsigned.all;
00072 
00073 
00074 ENTITY axi_basic_rx_pipeline IS
00075    GENERIC (
00076       C_DATA_WIDTH            : INTEGER := 128;           -- RX/TX interface data width
00077       C_FAMILY                : STRING := "X7";           -- Targeted FPGA family
00078       TCQ                     : INTEGER := 1;             -- Clock to Q time
00079 
00080       C_REM_WIDTH             : INTEGER := 1;             -- trem/rrem width
00081       C_STRB_WIDTH            : INTEGER := 4              -- TSTRB width
00082    );
00083    PORT (
00084 
00085       -- AXI RX
00086       -------------
00087       M_AXIS_RX_TDATA         : OUT STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0) ;       -- RX data to user
00088       M_AXIS_RX_TVALID        : OUT STD_LOGIC                                   ;       -- RX data is valid
00089       M_AXIS_RX_TREADY        : IN STD_LOGIC                                    ;       -- RX ready for data
00090       M_AXIS_RX_TSTRB         : OUT STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0) ;       -- RX strobe byte enables
00091       M_AXIS_RX_TLAST         : OUT STD_LOGIC                                   ;       -- RX data is last
00092       M_AXIS_RX_TUSER         : OUT STD_LOGIC_VECTOR(21 DOWNTO 0)               ;       -- RX user signals
00093 
00094        -- TRN RX
00095        -------------
00096       TRN_RD                  : IN STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0)  ;       -- RX data from block
00097       TRN_RSOF                : IN STD_LOGIC                                    ;       -- RX start of packet
00098       TRN_REOF                : IN STD_LOGIC                                    ;       -- RX end of packet
00099       TRN_RSRC_RDY            : IN STD_LOGIC                                    ;       -- RX source ready
00100       TRN_RDST_RDY            : OUT STD_LOGIC                                   ;       -- RX destination ready
00101       TRN_RSRC_DSC            : IN STD_LOGIC                                    ;       -- RX source discontinue
00102       TRN_RREM                : IN STD_LOGIC_VECTOR(C_REM_WIDTH - 1 DOWNTO 0)   ;       -- RX remainder
00103       TRN_RERRFWD             : IN STD_LOGIC                                    ;       -- RX error forward
00104       TRN_RBAR_HIT            : IN STD_LOGIC_VECTOR(6 DOWNTO 0)                 ;       -- RX BAR hit
00105       TRN_RECRC_ERR           : IN STD_LOGIC                                    ;       -- RX ECRC error
00106 
00107       -- Null Inputs
00108       -------------
00109       NULL_RX_TVALID          : IN STD_LOGIC                                    ;       -- NULL generated tvalid
00110       NULL_RX_TLAST           : IN STD_LOGIC                                    ;       -- NULL generated tlast
00111       NULL_RX_TSTRB           : IN STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0)  ;       -- NULL generated tstrb
00112       NULL_RDST_RDY           : IN STD_LOGIC                                    ;       -- NULL generated rdst_rdy
00113       NULL_IS_EOF             : IN STD_LOGIC_VECTOR(4 DOWNTO 0)                 ;       -- NULL generated is_eof
00114 
00115       -- System
00116       -------------
00117       NP_COUNTER              : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)                ;       -- Non-posted counter
00118       USER_CLK                : IN STD_LOGIC                                    ;       -- user clock from block
00119       USER_RST                : IN STD_LOGIC                                            -- user reset from block
00120    );
00121 END axi_basic_rx_pipeline;
00122 
00123 ARCHITECTURE trans OF axi_basic_rx_pipeline IS
00124 
00125    SIGNAL is_sof                 : STD_LOGIC_VECTOR(4 DOWNTO 0);
00126    SIGNAL is_sof_prev            : STD_LOGIC_VECTOR(4 DOWNTO 0);
00127 
00128    SIGNAL is_eof                 : STD_LOGIC_VECTOR(4 DOWNTO 0);
00129    SIGNAL is_eof_prev            : STD_LOGIC_VECTOR(4 DOWNTO 0);
00130 
00131    SIGNAL reg_tstrb              : STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0);
00132    SIGNAL tstrb                  : STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0);
00133    SIGNAL tstrb_prev             : STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0);
00134 
00135    SIGNAL reg_tlast              : STD_LOGIC;
00136    SIGNAL rsrc_rdy_filtered      : STD_LOGIC;
00137 
00138    SIGNAL trn_rd_DW_swapped      : STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0);
00139    SIGNAL trn_rd_prev            : STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0);
00140 
00141    SIGNAL data_hold              : STD_LOGIC;
00142    SIGNAL data_prev              : STD_LOGIC;
00143 
00144    SIGNAL trn_reof_prev          : STD_LOGIC;
00145    SIGNAL trn_rrem_prev          : STD_LOGIC_VECTOR(C_REM_WIDTH - 1 DOWNTO 0);
00146    SIGNAL trn_rsrc_rdy_prev      : STD_LOGIC;
00147    SIGNAL trn_rsrc_dsc_prev      : STD_LOGIC;
00148    SIGNAL trn_rsof_prev          : STD_LOGIC;
00149    SIGNAL trn_rbar_hit_prev      : STD_LOGIC_VECTOR(6 DOWNTO 0);
00150    SIGNAL trn_rerrfwd_prev       : STD_LOGIC;
00151    SIGNAL trn_recrc_err_prev     : STD_LOGIC;
00152 
00153    -- Null packet handling signals
00154    SIGNAL null_mux_sel           : STD_LOGIC;
00155    SIGNAL trn_in_packet          : STD_LOGIC;
00156    SIGNAL dsc_flag               : STD_LOGIC;
00157    SIGNAL dsc_detect             : STD_LOGIC;
00158    SIGNAL reg_dsc_detect         : STD_LOGIC;
00159    SIGNAL trn_rsrc_dsc_d         : STD_LOGIC;
00160 
00161    -- Declare intermediate signals for referenced outputs
00162    SIGNAL m_axis_rx_tdata_xhdl0  : STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0);
00163    SIGNAL m_axis_rx_tvalid_xhdl2 : STD_LOGIC;
00164    SIGNAL m_axis_rx_tuser_xhdl1  : STD_LOGIC_VECTOR(21 DOWNTO 0);
00165    SIGNAL trn_rdst_rdy_xhdl4     : STD_LOGIC;
00166    SIGNAL mrd_lower              : STD_LOGIC;
00167    SIGNAL mrd_lk_lower           : STD_LOGIC;
00168    SIGNAL io_rdwr_lower          : STD_LOGIC;
00169    SIGNAL cfg_rdwr_lower         : STD_LOGIC;
00170    SIGNAL atomic_lower           : STD_LOGIC;
00171    SIGNAL np_pkt_lower           : STD_LOGIC;
00172    SIGNAL mrd_upper              : STD_LOGIC;
00173    SIGNAL mrd_lk_upper           : STD_LOGIC;
00174    SIGNAL io_rdwr_upper          : STD_LOGIC;
00175    SIGNAL cfg_rdwr_upper         : STD_LOGIC;
00176    SIGNAL atomic_upper           : STD_LOGIC;
00177    SIGNAL np_pkt_upper           : STD_LOGIC;
00178    SIGNAL pkt_accepted           : STD_LOGIC;
00179    SIGNAL reg_np_counter         : STD_LOGIC_VECTOR(2 DOWNTO 0);
00180 
00181 BEGIN
00182    -- Drive referenced outputs
00183    M_AXIS_RX_TDATA     <= m_axis_rx_tdata_xhdl0;
00184    M_AXIS_RX_TVALID    <= m_axis_rx_tvalid_xhdl2;
00185    M_AXIS_RX_TUSER     <= m_axis_rx_tuser_xhdl1;
00186    TRN_RDST_RDY        <= trn_rdst_rdy_xhdl4;
00187 
00188    -- Create "filtered" version of rsrc_rdy, where discontinued SOFs are removed
00189    rsrc_rdy_filtered <= trn_rsrc_rdy AND (trn_in_packet OR (trn_rsof AND NOT trn_rsrc_dsc));
00190 
00191    --------------------------------------------------------------------------------
00192    -- Previous value buffer                                                      --
00193    -- ---------------------                                                      --
00194    -- We are inserting a pipeline stage in between TRN and AXI, which causes     --
00195    -- some issues with handshaking signals m_axis_rx_tready/trn_rdst_rdy. The    --
00196    -- added cycle of latency in the path causes the user design to fall behind   --
00197    -- the TRN interface whenever it throttles.                                   --
00198    --                                                                            --
00199    -- To avoid loss of data, we must keep the previous value of all trn_r*       --
00200    -- signals in case the user throttles.                                        --
00201    --------------------------------------------------------------------------------
00202    PROCESS (USER_CLK)
00203    BEGIN
00204       IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
00205          IF (USER_RST = '1') THEN
00206             trn_rd_prev        <=  (others => '0')AFTER 1 ps;
00207             trn_rsof_prev      <=  '0'  AFTER (TCQ)*1 ps;
00208             trn_rrem_prev      <=  (others => '0') AFTER (TCQ)*1 ps;
00209             trn_rsrc_rdy_prev  <=  '0' AFTER 1 ps;
00210             trn_rbar_hit_prev  <=  (others => '0') AFTER 1 ps;
00211             trn_rerrfwd_prev   <=  '0' AFTER 1 ps;
00212             trn_recrc_err_prev <=  '0' AFTER 1 ps;
00213             trn_reof_prev      <=  '0' AFTER 1 ps;
00214             trn_rsrc_dsc_prev  <=  '0' AFTER 1 ps;
00215          ELSE
00216                   -- prev buffer works by checking trn_rdst_rdy. When trn_rdst_rdy is
00217                   -- asserted, a new value is present on the interface.
00218 
00219             IF (trn_rdst_rdy_xhdl4 = '1') THEN
00220                trn_rd_prev        <= trn_rd_DW_swapped  AFTER (TCQ)*1 ps;
00221                trn_rsof_prev      <= TRN_RSOF           AFTER (TCQ)*1 ps;
00222                trn_rrem_prev      <= TRN_RREM           AFTER (TCQ)*1 ps;
00223                trn_rbar_hit_prev  <= TRN_RBAR_HIT       AFTER (TCQ)*1 ps;
00224                trn_rerrfwd_prev   <= TRN_RERRFWD        AFTER (TCQ)*1 ps;
00225                trn_recrc_err_prev <= TRN_RECRC_ERR      AFTER (TCQ)*1 ps;
00226                trn_rsrc_rdy_prev  <= rsrc_rdy_filtered  AFTER (TCQ)*1 ps;
00227                trn_reof_prev      <= trn_reof           AFTER (TCQ)*1 ps;
00228                trn_rsrc_dsc_prev  <= TRN_RSRC_DSC OR dsc_flag AFTER (TCQ)*1 ps;
00229             END IF;
00230          END IF;
00231       END IF;
00232    END PROCESS;
00233 
00234   --------------------------------------------------------------------------------
00235   -- Create TDATA
00236   ------------------------------------------------------------------------------
00237   -- Convert TRN data format to AXI data format. AXI is DWORD swapped from TRN
00238   -- 128-bit:                 64-bit:                  32-bit:
00239   -- TRN DW0 maps to AXI DW3  TRN DW0 maps to AXI DW1  TNR DW0 maps to AXI DW0
00240   -- TRN DW1 maps to AXI DW2  TRN DW1 maps to AXI DW0
00241   -- TRN DW2 maps to AXI DW1
00242   -- TRN DW3 maps to AXI DW0
00243 
00244    xhdl7 : IF (C_DATA_WIDTH = 128) GENERATE
00245       trn_rd_DW_swapped <= (TRN_RD(31 DOWNTO 0) & TRN_RD(63 DOWNTO 32) & TRN_RD(95 DOWNTO 64) & TRN_RD(127 DOWNTO 96));
00246    END GENERATE;
00247    --xhdl8 : IF (NOT(C_DATA_WIDTH = 128)) GENERATE
00248    xhdl9 : IF (C_DATA_WIDTH = 64) GENERATE
00249            trn_rd_DW_swapped <= (TRN_RD(31 DOWNTO 0) & TRN_RD(63 DOWNTO 32));
00250    END GENERATE;
00251 
00252    xhdl10 : IF (NOT(C_DATA_WIDTH = 64) AND NOT(C_DATA_WIDTH = 128)) GENERATE
00253            trn_rd_DW_swapped <= TRN_RD;
00254    END GENERATE;
00255    --END GENERATE;
00256 
00257    -- Create special buffer which locks in the proper value of TDATA depending
00258    -- on whether the user is throttling or not. This buffer has three states:
00259    --
00260    --   HOLD state: TDATA maintains its current value
00261    --                   - the user has throttled the PCIe block
00262    --   PREVIOUS state: the buffer provides the previous value on trn_rd
00263    --                   - the user has finished throttling, and is a little behind
00264    --                     the PCIe block
00265    --   CURRENT state: the buffer passes the current value on trn_rd
00266    --                   - the user is caught up and ready to receive the latest
00267    --                     data from the PCIe block
00268 
00269    PROCESS (USER_CLK)
00270    BEGIN
00271            IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
00272                    IF (USER_RST = '1') THEN
00273                            m_axis_rx_tdata_xhdl0 <= (OTHERS=>'0') AFTER (TCQ)*1 ps;
00274                    ELSE
00275                            IF ((NOT(data_hold)) = '1') THEN
00276                                     -- PREVIOUS state
00277                                    IF (data_prev = '1') THEN
00278                                            m_axis_rx_tdata_xhdl0 <= trn_rd_prev  AFTER (TCQ)*1 ps;
00279                                    -- CURRENT state
00280                                    ELSE
00281                                            m_axis_rx_tdata_xhdl0 <= trn_rd_DW_swapped  AFTER (TCQ)*1 ps;
00282                                    END IF;
00283                            END IF;
00284                            -- else HOLD state
00285                    END IF;
00286            END IF;
00287    END PROCESS;
00288 
00289    -- Logic to instruct pipeline to hold its value
00290    data_hold <= (NOT(M_AXIS_RX_TREADY) AND m_axis_rx_tvalid_xhdl2);
00291 
00292    -- Logic to instruct pipeline to use previous bus values. Always use previous value after holding a value.
00293    PROCESS (USER_CLK)
00294    BEGIN
00295       IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
00296          IF (USER_RST = '1') THEN
00297             data_prev <= '0'  AFTER (TCQ)*1 ps;
00298          ELSE
00299             data_prev <= data_hold  AFTER (TCQ)*1 ps;
00300          END IF;
00301       END IF;
00302    END PROCESS;
00303 
00304    ------------------------------------------------------------------------------
00305    -- Create TVALID, TLAST, TSTRB, TUSER
00306    -- -----------------------------------
00307    -- Use the same strategy for these signals as for TDATA, except here we need
00308    -- an extra provision for null packets.
00309    ------------------------------------------------------------------------------
00310    PROCESS (USER_CLK)
00311    BEGIN
00312       IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
00313               IF (USER_RST = '1') THEN
00314                       m_axis_rx_tvalid_xhdl2 <= '0'  AFTER (TCQ)*1 ps;
00315                       reg_tlast <= '0' AFTER (TCQ)*1 ps;
00316                       reg_tstrb <= (others => '1') AFTER (TCQ)*1 ps;
00317                       m_axis_rx_tuser_xhdl1 <= (others => '0')  AFTER (TCQ)*1 ps;
00318               ELSE
00319                  IF (data_hold = '0') THEN
00320                       -- If in a null packet, use null generated value
00321                       IF (null_mux_sel = '1') THEN
00322                               m_axis_rx_tvalid_xhdl2 <= NULL_RX_TVALID  AFTER (TCQ)*1 ps;
00323                               reg_tlast <= NULL_RX_TLAST AFTER (TCQ)*1 ps;
00324                               reg_tstrb <= NULL_RX_TSTRB AFTER (TCQ)*1 ps;
00325                               m_axis_rx_tuser_xhdl1 <= (NULL_IS_EOF & "00000000000000000") AFTER (TCQ)*1 ps;
00326 
00327                       -- PREVIOUS state
00328                       ELSIF (data_prev = '1') THEN
00329                               m_axis_rx_tvalid_xhdl2 <= (trn_rsrc_rdy_prev  OR dsc_flag) AFTER (TCQ)*1 ps;
00330                               reg_tlast <= trn_reof_prev AFTER (TCQ)*1 ps;
00331                               reg_tstrb <= tstrb_prev AFTER (TCQ)*1 ps;
00332                               m_axis_rx_tuser_xhdl1 <= (is_eof_prev & "00" & is_sof_prev & '0' & trn_rbar_hit_prev & trn_rerrfwd_prev & trn_recrc_err_prev) AFTER (TCQ)*1 ps;
00333                                               -- TUSER bits [21:17] & TUSER bits [16:15] & TUSER bits [14:10] & TUSER bits [9] & TUSER bits [8:2] & TUSER bit  [1] & TUSER bit  [0]
00334 
00335                       -- CURRENT state
00336                       ELSE
00337 
00338                               m_axis_rx_tvalid_xhdl2 <= (rsrc_rdy_filtered OR dsc_flag) AFTER (TCQ)*1 ps;
00339                               reg_tlast <= TRN_REOF AFTER (TCQ)*1 ps;
00340                               reg_tstrb <= tstrb AFTER (TCQ)*1 ps;
00341                               m_axis_rx_tuser_xhdl1 <= (is_eof & "00" & is_sof & '0' & trn_rbar_hit & TRN_RERRFWD & TRN_RECRC_ERR) AFTER (TCQ)*1 ps;
00342                                                   -- TUSER bits [21:17] & TUSER bits [16:15] & TUSER bits [14:10] & TUSER bits [9] & TUSER bits [8:2] & TUSER bit  [1] & TUSER bit  [0]
00343                        END IF;
00344                  END IF;
00345                  -- else HOLD state
00346               END IF;
00347       END IF;
00348    END PROCESS;
00349 
00350 -- Hook up TLAST and TSTRB depending on interface width
00351    xhdl11 : IF (C_DATA_WIDTH = 128) GENERATE
00352             -- For 128-bit interface, don't pass TLAST and TSTRB to user (is_eof and is_data passed to user instead). reg_tlast is still used internally.
00353            M_AXIS_RX_TLAST <= '0';
00354            M_AXIS_RX_TSTRB <= (others => '1');
00355    END GENERATE;
00356 
00357 
00358  -- For 64/32-bit interface, pass TLAST to user.
00359    xhdl12 : IF (NOT(C_DATA_WIDTH = 128)) GENERATE
00360            M_AXIS_RX_TLAST <= reg_tlast;
00361            M_AXIS_RX_TSTRB <= reg_tstrb;
00362    END GENERATE;
00363 
00364    --------------------------------------------------------------------------------
00365    -- Create TSTRB                                                              ---
00366    -- ------------                                                              ---
00367    -- Convert RREM to STRB. Here, we are converting the encoding method for the ---
00368    -- location of the EOF from TRN flavor (rrem) to AXI (TSTRB).                ---
00369    --                                                                           ---
00370    -- NOTE: for each configuration, we need two values of TSTRB, the current and---
00371    --       previous values. The need for these two values is described below.  ---
00372    --------------------------------------------------------------------------------
00373    xhdl13 : IF (C_DATA_WIDTH = 128) GENERATE
00374            -- TLAST and TSTRB not used in 128-bit interface. is_sof and is_eof used instead.
00375            tstrb <= x"0000";
00376            tstrb_prev <= x"0000";
00377    END GENERATE;
00378 
00379    xhdl14 : IF (C_DATA_WIDTH /= 128) GENERATE
00380            xhdl15 : IF (C_DATA_WIDTH = 64) GENERATE
00381                    -- 64-bit interface: contains 2 DWORDs per cycle, for a total of 8 bytes
00382                    -- TSTRB has only two possible values here, 0xFF or 0x0F
00383                    tstrb      <= x"FF" WHEN (TRN_RREM = "11") ELSE x"0F";
00384                    tstrb_prev <= x"FF" WHEN (trn_rrem_prev = "11" ) ELSE x"0F";
00385            END GENERATE;
00386            xhdl16 : IF (C_DATA_WIDTH /= 64) GENERATE
00387                    -- 32-bit interface: contains 1 DWORD per cycle, for a total of 4 bytes
00388                    -- TSTRB is always 0xF in this case, due to the nature of the PCIe block
00389                    tstrb      <= "1111";
00390                    tstrb_prev <= "1111";
00391            END GENERATE;
00392    END GENERATE;
00393 
00394    ------------------------------------------------------------------------------//
00395    -- Create is_sof                                                              //
00396    -- -------------                                                              //
00397    -- is_sof is a signal to the user indicating the location of SOF in TDATA   . //
00398    -- Due to inherent 64-bit alignment of packets from the block, the only       //
00399    -- possible values are:                                                       //
00400    --                      Value                      Valid data widths          //
00401    --                      5'b11000 (sof @ byte 8)    128                        //
00402    --                      5'b10000 (sof @ byte 0)    128, 64, 32                //
00403    --                      5'b00000 (sof not present) 128, 64, 32                //
00404    ------------------------------------------------------------------------------//
00405    xhdl17 : IF (C_DATA_WIDTH = 128) GENERATE
00406            is_sof <= (((NOT(TRN_RSRC_DSC)) AND TRN_RSOF) & ((NOT(TRN_RREM(1))) AND TRN_RSOF ) & "000");
00407            is_sof_prev <= (((trn_rsof_prev AND (NOT(trn_rsrc_dsc_prev)))) & (trn_rsof_prev AND (NOT(trn_rrem_prev(1)))) & "000");
00408                           -- bit 4:   enable bit 3:   sof @ byte 8? bit 2-0: hardwired 0
00409    END GENERATE;
00410 
00411    xhdl18 : IF (NOT(C_DATA_WIDTH = 128)) GENERATE
00412            is_sof      <= ((TRN_RSOF AND (NOT TRN_RSRC_DSC)) & "0000"); -- bit 4: enable, bits 3-0: hardwired 0
00413            is_sof_prev <= ((trn_rsof_prev AND (NOT trn_rsrc_dsc_prev)) & "0000");
00414    END GENERATE;
00415 
00416    ------------------------------------------------------------------------------//
00417    -- Create is_eof                                                              //
00418    -- -------------                                                              //
00419    -- is_eof is a signal to the user indicating the location of EOF in TDATA   . //
00420    -- Due to DWORD granularity of packets from the block, the only               //
00421    -- possible values are:                                                       //
00422    --                      Value                      Valid data widths          //
00423    --                      5'b11111 (eof @ byte 15)   128                        //
00424    --                      5'b11011 (eof @ byte 11)   128                        //
00425    --                      5'b10111 (eof @ byte 7)    128, 64                    //
00426    --                      5'b10011 (eof @ byte 3)`   128, 64, 32                //
00427    --                      5'b00011 (eof not present) 128, 64, 32                //
00428    ------------------------------------------------------------------------------//
00429    xhdl19 : IF (C_DATA_WIDTH = 128) GENERATE
00430            is_eof       <= (TRN_REOF & TRN_RREM & "11");
00431            is_eof_prev  <= (trn_reof_prev & trn_rrem_prev & "11");
00432            -- bit 4:   enable bit 3-2: encoded eof loc from block  bit 1-0: hardwired 1
00433    END GENERATE;
00434 
00435    xhdl20 : IF (C_DATA_WIDTH = 64) GENERATE
00436            is_eof       <= (TRN_REOF & '0' & TRN_RREM & "11");
00437            is_eof_prev  <= (trn_reof_prev & '0' & trn_rrem_prev & "11");
00438            -- bit 4: enable, bit 3: hardwired 0, bit 2: encoded eof loc from  block, bit 1-0: hardwired 1
00439    END GENERATE;
00440 
00441    --------------------------------------------------------------------------------
00442    xhdl20A : IF (C_DATA_WIDTH = 32) GENERATE
00443            is_eof       <= (TRN_REOF & "0011");
00444            is_eof_prev  <= (trn_reof_prev & "0011");
00445            -- bit 4: enable, bit 3: hardwired 0, bit 2: encoded eof loc from  block, bit 1-0: hardwired 1
00446    END GENERATE;
00447 
00448 
00449    -- Create trn_rdst_rdy                                                        --
00450    --------------------------------------------------------------------------------
00451    PROCESS (USER_CLK)
00452    BEGIN
00453       IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
00454               IF (USER_RST = '1') THEN
00455                       trn_rdst_rdy_xhdl4 <= '0' AFTER (TCQ)*1 ps;
00456               ELSE
00457                       -- If in a null packet, use null generated value
00458                       IF (null_mux_sel = '1' AND M_AXIS_RX_TREADY = '1') THEN
00459                               trn_rdst_rdy_xhdl4 <= NULL_RDST_RDY AFTER (TCQ)*1 ps;
00460                       -- If a discontinue needs to be serviced, throttle the block until we are
00461                       -- ready to pad out the packet
00462                       ELSIF (dsc_flag = '1') THEN
00463                               trn_rdst_rdy_xhdl4 <= '0' AFTER (TCQ)*1 ps;
00464                       -- If in a packet, pass user back-pressure directly to block
00465                       ELSIF (m_axis_rx_tvalid_xhdl2 = '1') THEN
00466                               trn_rdst_rdy_xhdl4 <= M_AXIS_RX_TREADY AFTER (TCQ)*1 ps;
00467                       -- If idle, default to no back-pressure. We need to default to the
00468                       -- "ready to accept data" state to make sure we catch the first
00469                       -- clock of data of a new packet.
00470                       ELSE
00471                               trn_rdst_rdy_xhdl4 <= '1' AFTER (TCQ)*1 ps;
00472                       END IF;
00473               END IF;
00474       END IF;
00475    END PROCESS;
00476 
00477    ------------------------------------------------------------------------------//
00478    -- Create null_mux_sel                                                        //
00479    -- null_mux_sel is the signal used to detect a discontinue situation and      //
00480    -- mux in the null packet generated in rx_null_gen. Only mux in null data     //
00481    -- when not at the beginningof a packet. SOF discontinues do not require      //
00482    -- padding, as the whole packet is simply squashed instead.                   //
00483    ------------------------------------------------------------------------------//
00484    PROCESS (USER_CLK)
00485    BEGIN
00486       IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
00487               IF (USER_RST = '1') THEN
00488                       null_mux_sel <= '0' AFTER (TCQ)*1 ps;
00489               ELSE
00490                       -- NULL packet done
00491                       IF (null_mux_sel = '1' AND NULL_RX_TLAST = '1' AND M_AXIS_RX_TREADY = '1') THEN
00492                               null_mux_sel <= '0' AFTER (TCQ)*1 ps;
00493                       -- Discontinue detected and we're in packet, so switch to NULL packet
00494                       ELSIF (dsc_flag = '1' AND data_hold = '0') THEN
00495                               null_mux_sel <= '1' AFTER (TCQ)*1 ps;
00496                       END IF;
00497               END IF;
00498       END IF;
00499    END PROCESS;
00500 
00501    ------------------------------------------------------------------------------//
00502    -- Create discontinue tracking signals                                        //
00503    ------------------------------------------------------------------------------//
00504    -- Create signal trn_in_packet, which is needed to validate trn_rsrc_dsc. We
00505    -- should ignore trn_rsrc_dsc when it's asserted out-of-packet.
00506    PROCESS (USER_CLK)
00507    BEGIN
00508       IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
00509               IF (USER_RST = '1') THEN
00510                       trn_in_packet <= '0' AFTER (TCQ)*1 ps;
00511               ELSE
00512                       IF ((TRN_RSOF = '1') AND (NOT(TRN_REOF = '1')) AND rsrc_rdy_filtered = '1' AND trn_rdst_rdy_xhdl4 = '1') THEN
00513                               trn_in_packet <= '1' AFTER (TCQ)*1 ps;
00514                       ELSIF (TRN_RSRC_DSC = '1') THEN
00515                               trn_in_packet <= '0' AFTER (TCQ)*1 ps;
00516                       ELSIF (TRN_REOF= '1' AND (NOT(TRN_RSOF= '1')) AND TRN_RSRC_RDY = '1' AND trn_rdst_rdy_xhdl4 = '1') THEN
00517                               trn_in_packet <= '0';
00518                       END IF;
00519               END IF;
00520       END IF;
00521    END PROCESS;
00522 
00523    -- Create dsc_flag, which identifies and stores mid-packet discontinues that
00524    -- require null packet padding. This signal is edge sensitive to trn_rsrc_dsc,
00525    -- to make sure we don't service the same dsc twice in the event that
00526    -- trn_rsrc_dsc stays asserted for longer than it takes to pad out the packet.
00527 
00528    dsc_detect <= TRN_RSRC_DSC and (not(trn_rsrc_dsc_d)) and trn_in_packet and ((not(TRN_RSOF)) or TRN_REOF) and (not(trn_rdst_rdy_xhdl4 and TRN_REOF));
00529 
00530    PROCESS (USER_CLK,USER_RST)
00531    BEGIN
00532            IF (USER_CLk'EVENT AND USER_CLK = '1') THEN
00533                    IF (USER_RST = '1') THEN
00534                            reg_dsc_detect <= '0' AFTER (TCQ)*1 ps;
00535                            trn_rsrc_dsc_d <= '0' AFTER (TCQ)*1 ps;
00536                    ELSE
00537                            IF (dsc_detect = '1') THEN
00538                                    reg_dsc_detect <= '1' AFTER (TCQ)*1 ps;
00539                            ELSIF (null_mux_sel = '1') THEN
00540                                    reg_dsc_detect <= '0' AFTER (TCQ)*1 ps;
00541                            END IF;
00542 
00543                            trn_rsrc_dsc_d <= TRN_RSRC_DSC AFTER (TCQ)*1 ps;
00544                    END IF;
00545            END IF;
00546    END PROCESS;
00547 
00548    dsc_flag <= dsc_detect OR reg_dsc_detect;
00549 
00550    --------------------------------------------------------------------------------
00551    -- Create np_counter (V6 128-bit only). This counter tells the V6 128-bit     --
00552    -- interface core how many NP packets have left the RX pipeline. The V6       --
00553    -- 128-bit interface uses this count to perform rnp_ok modulation.            --
00554    --------------------------------------------------------------------------------
00555 
00556    xhdl21 : IF ((C_FAMILY = "V6") AND (C_DATA_WIDTH = 128)) GENERATE
00557       -- Look for NP packets beginning on lower (i.e. unaligned) start
00558       mrd_lower      <= '1' WHEN (m_axis_rx_tdata_xhdl0(92 DOWNTO 88) = "00000" AND m_axis_rx_tdata_xhdl0(94) = '0') ELSE '0';
00559       mrd_lk_lower   <= '1' WHEN (m_axis_rx_tdata_xhdl0(92 DOWNTO 88) = "00001") ELSE '0';
00560       io_rdwr_lower  <= '1' WHEN (m_axis_rx_tdata_xhdl0(92 DOWNTO 88) = "00010") ELSE '0';
00561       cfg_rdwr_lower <= '1' WHEN (m_axis_rx_tdata_xhdl0(92 DOWNTO 89) = "0010") ELSE '0';
00562       atomic_lower   <= '1' WHEN (m_axis_rx_tdata_xhdl0(91 DOWNTO 90) = "11" AND m_axis_rx_tdata_xhdl0(94) = '1') ELSE '0';
00563 
00564       np_pkt_lower <= '1' WHEN ((mrd_lower = '1'      OR
00565                                  mrd_lk_lower = '1'   OR
00566                                  io_rdwr_lower = '1'  OR
00567                                  cfg_rdwr_lower = '1' OR
00568                                  atomic_lower = '1') AND m_axis_rx_tuser_xhdl1(13) = '1') ELSE '0';
00569 
00570       -- Look for NP packets beginning on upper (i.e. aligned) start
00571       mrd_upper      <= '1' WHEN (m_axis_rx_tdata_xhdl0(28 DOWNTO 24) = "00000" AND m_axis_rx_tdata_xhdl0(30) = '0') ELSE '0';
00572       mrd_lk_upper   <= '1' WHEN (m_axis_rx_tdata_xhdl0(28 DOWNTO 24) = "00001") ELSE '0';
00573       io_rdwr_upper  <= '1' WHEN (m_axis_rx_tdata_xhdl0(28 DOWNTO 24) = "00010") ELSE '0';
00574       cfg_rdwr_upper <= '1' WHEN (m_axis_rx_tdata_xhdl0(28 DOWNTO 25) = "0010") ELSE '0';
00575       atomic_upper   <= '1' WHEN (m_axis_rx_tdata_xhdl0(27 DOWNTO 26) = "11" AND m_axis_rx_tdata_xhdl0(30) = '1') ELSE '0';
00576 
00577       np_pkt_upper <= '1' WHEN ((mrd_upper = '1'      OR
00578                                  mrd_lk_upper = '1'   OR
00579                                  io_rdwr_upper = '1'  OR
00580                                  cfg_rdwr_upper = '1' OR
00581                                  atomic_upper = '1') AND m_axis_rx_tuser_xhdl1(13) = '0') ELSE '0';
00582 
00583       pkt_accepted <= '1' WHEN (m_axis_rx_tuser_xhdl1(14) = '1' AND M_AXIS_RX_TREADY = '1' AND m_axis_rx_tvalid_xhdl2 = '1') ELSE '0';
00584 
00585       -- Increment counter whenever an NP packet leaves the RX pipeline
00586       PROCESS (USER_CLK)
00587       BEGIN
00588               IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
00589                       IF (USER_RST = '1') THEN
00590                               reg_np_counter <= "000" AFTER (TCQ)*1 ps;
00591                       ELSE
00592                               IF ((np_pkt_lower = '1' OR np_pkt_upper = '1') AND pkt_accepted = '1') THEN
00593                                       reg_np_counter <= reg_np_counter + "001" AFTER (TCQ)*1 ps;
00594                               END IF;
00595                       END IF;
00596               END IF;
00597       END PROCESS;
00598 
00599       NP_COUNTER <= reg_np_counter;
00600    END GENERATE;
00601 
00602    xhdl22 : IF (NOT(C_FAMILY = "V6" AND C_DATA_WIDTH = 128)) GENERATE
00603            NP_COUNTER <= "000";
00604    END GENERATE;
00605 END trans;
00606 
00607