DS_DMA
|
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