DS_DMA
|
00001 ------------------------------------------------------------------------------- 00002 -- 00003 -- Title : core64_rx_engine 00004 -- Author : Dmitry Smekhov 00005 -- Company : Instrumental Systems 00006 -- E-mail : dsmv@insys.ru 00007 -- 00008 -- Version : 1.0 00009 -- 00010 ------------------------------------------------------------------------------- 00011 -- 00012 -- Description : Обработчик входящих пакетов 00013 -- 00014 ------------------------------------------------------------------------------- 00015 00016 00017 library ieee; 00018 use ieee.std_logic_1164.all; 00019 00020 use work.core64_type_pkg.all; 00021 00022 package core64_rx_engine_pkg is 00023 00024 component core64_rx_engine is 00025 port( 00026 00027 --- General --- 00028 rstp : in std_logic; --! 1 - сброс 00029 clk : in std_logic; --! тактовая частота ядра - 250 MHz 00030 00031 trn_rx : in type_trn_rx; --! приём пакета 00032 trn_rx_back : out type_trn_rx_back; --! готовность к приёму пакета 00033 00034 reg_access : out type_reg_access; --! запрос на доступ к регистрам 00035 00036 rx_tx_engine : out type_rx_tx_engine; --! обмен RX->TX 00037 tx_rx_engine : in type_tx_rx_engine; --! обмен TX->RX 00038 00039 rx_ext_fifo : out type_rx_ext_fifo --! обмен RX->EXT_FIFO 00040 00041 00042 00043 ); 00044 end component; 00045 00046 end package; 00047 00048 library ieee; 00049 use ieee.std_logic_1164.all; 00050 use ieee.std_logic_arith.all; 00051 use ieee.std_logic_unsigned.all; 00052 00053 use work.core64_type_pkg.all; 00054 00055 entity core64_rx_engine is 00056 port( 00057 00058 --- General --- 00059 rstp : in std_logic; --! 1 - сброс 00060 clk : in std_logic; --! тактовая частота ядра - 250 MHz 00061 00062 trn_rx : in type_trn_rx; --! приём пакета 00063 trn_rx_back : out type_trn_rx_back; --! готовность к приёму пакета 00064 00065 reg_access : out type_reg_access; --! запрос на доступ к регистрам 00066 00067 rx_tx_engine : out type_rx_tx_engine; --! обмен RX->TX 00068 tx_rx_engine : in type_tx_rx_engine; --! обмен TX->RX 00069 00070 rx_ext_fifo : out type_rx_ext_fifo --! обмен RX->EXT_FIFO 00071 00072 00073 00074 ); 00075 end core64_rx_engine; 00076 00077 00078 architecture core64_rx_engine of core64_rx_engine is 00079 00080 component ctrl_fifo64x70st is 00081 port ( 00082 clk : in std_logic; 00083 rst : in std_logic; 00084 din : in std_logic_vector(69 downto 0); 00085 wr_en : in std_logic; 00086 rd_en : in std_logic; 00087 dout : out std_logic_vector(69 downto 0); 00088 full : out std_logic; 00089 empty : out std_logic; 00090 valid : out std_logic; 00091 prog_full : out std_logic; 00092 prog_empty : out std_logic 00093 ); 00094 end component; 00095 00096 00097 signal rstpz : std_logic; 00098 00099 type stp_type is ( s0, s1, s2, s3, s31, s32, s4, s5 ); 00100 signal stp : stp_type; 00101 00102 type stf_type is ( s0, s1, s2, s3, s4, s5, s6 ); 00103 signal stf : stf_type; 00104 00105 signal trn_rdst_rdy_n : std_logic; 00106 signal trn_rnp_ok_n : std_logic; 00107 signal trn_rcpl_streaming_n : std_logic; 00108 00109 signal tlp_dw0 : std_logic_vector( 31 downto 0 ); 00110 signal tlp_dw1 : std_logic_vector( 31 downto 0 ); 00111 signal tlp_dw2 : std_logic_vector( 31 downto 0 ); 00112 signal tlp_dw3 : std_logic_vector( 31 downto 0 ); 00113 00114 signal trn_data : std_logic_vector( 63 downto 0 ); 00115 signal trn_data_we : std_logic; 00116 00117 signal tlp_cnt : std_logic_vector( 5 downto 0 ); 00118 00119 signal request_reg_wr : std_logic; 00120 signal request_reg_rd : std_logic; 00121 signal tlp_complete : std_logic; 00122 signal bar : std_logic_vector( 1 downto 0 ); 00123 00124 signal fifo_wr : std_logic; 00125 signal fifo_wr_z : std_logic; 00126 signal fifo_din : std_logic_vector( 69 downto 0 ); 00127 00128 signal fifo0_wr : std_logic; 00129 signal fifo0_wr_en : std_logic; 00130 signal fifo0_wr_en_z : std_logic; 00131 signal fifo0_rd : std_logic; 00132 signal fifo0_full : std_logic; 00133 signal fifo0_empty : std_logic; 00134 signal fifo0_valid : std_logic; 00135 signal fifo0_paf : std_logic; 00136 signal fifo0_pae : std_logic; 00137 signal fifo0_dout : std_logic_vector( 69 downto 0 ); 00138 00139 signal fifo1_wr : std_logic; 00140 signal fifo1_wr_en : std_logic; 00141 signal fifo1_wr_en_z : std_logic; 00142 signal fifo1_rd : std_logic; 00143 signal fifo1_rd_x : std_logic; 00144 signal fifo1_full : std_logic; 00145 signal fifo1_empty : std_logic; 00146 signal fifo1_valid : std_logic; 00147 signal fifo1_paf : std_logic; 00148 signal fifo1_pae : std_logic; 00149 signal fifo1_dout : std_logic_vector( 69 downto 0 ); 00150 00151 signal data_rx : std_logic_vector( 63 downto 0 ); 00152 signal data_rx_we : std_logic; 00153 signal data_rx_we_en : std_logic; 00154 signal data_lrx : std_logic_vector( 31 downto 0 ); 00155 signal data_hrx : std_logic_vector( 31 downto 0 ); 00156 00157 signal tlp_cp_dw0 : std_logic_vector( 31 downto 0 ); 00158 signal tlp_cp_dw1 : std_logic_vector( 31 downto 0 ); 00159 signal tlp_cp_dw2 : std_logic_vector( 31 downto 0 ); 00160 signal tlp_cp_dw3 : std_logic_vector( 31 downto 0 ); 00161 00162 signal adr_rx : std_logic_vector( 8 downto 0 ); 00163 signal adr_cnt : std_logic_vector( 3 downto 0 ); 00164 00165 begin 00166 00167 rstpz <= rstp after 1 ns when rising_edge( clk ); 00168 00169 trn_rx_back.trn_rdst_rdy_n <= trn_rdst_rdy_n; 00170 trn_rx_back.trn_rnp_ok_n <= trn_rnp_ok_n; 00171 trn_rx_back.trn_rcpl_streaming_n <= trn_rcpl_streaming_n; 00172 00173 trn_rnp_ok_n <= '0'; 00174 trn_rcpl_streaming_n <= '0'; 00175 00176 trn_rdst_rdy_n <= fifo0_paf or fifo1_paf; 00177 00178 fifo_wr <= not ( trn_rx.trn_rsrc_rdy_n or trn_rdst_rdy_n ); 00179 fifo_wr_z <= fifo_wr after 1 ns when rising_edge( clk ); 00180 00181 fifo_din <= not trn_rx.trn_rbar_hit_n(1) & not trn_rx.trn_rbar_hit_n(0) & 00182 trn_rx.trn_rerrfwd_n & trn_rx.trn_rrem_n(0) & trn_rx.trn_reof_n & trn_rx.trn_rsof_n & 00183 trn_rx.trn_rd after 1 ns when rising_edge( clk ); 00184 00185 pr_fifo0_wr: process( clk ) begin 00186 if( rising_edge( clk ) ) then 00187 if( rstpz='1' or (fifo_wr='1' and trn_rx.trn_reof_n='0' ) ) then 00188 fifo0_wr_en <= '0' after 1 ns; 00189 elsif( fifo_wr='1' and trn_rx.trn_rd(63)='0' and trn_rx.trn_rd(61 downto 57)="00000" and trn_rx.trn_rsof_n='0' ) then 00190 fifo0_wr_en <= '1' after 1 ns; 00191 end if; 00192 end if; 00193 end process; 00194 00195 fifo0_wr_en_z <= fifo0_wr_en after 1 ns when rising_edge( clk ); 00196 00197 fifo0_wr <= fifo_wr_z and (fifo0_wr_en or fifo0_wr_en_z); 00198 00199 fifo0_reg: ctrl_fifo64x70st 00200 port map( 00201 clk => clk, 00202 rst => rstpz, 00203 din => fifo_din, 00204 wr_en => fifo0_wr, 00205 rd_en => fifo0_rd, 00206 dout => fifo0_dout, 00207 full => fifo0_full, 00208 empty => fifo0_empty, 00209 valid => fifo0_valid, 00210 prog_full => fifo0_paf, 00211 prog_empty => fifo0_pae 00212 ); 00213 00214 00215 pr_fifo1_wr: process( clk ) begin 00216 if( rising_edge( clk ) ) then 00217 if( rstpz='1' or (fifo_wr='1' and trn_rx.trn_reof_n='0' ) ) then 00218 fifo1_wr_en <= '0' after 1 ns; 00219 elsif( fifo_wr='1' and trn_rx.trn_rd(63 downto 57)="0100101" and trn_rx.trn_rsof_n='0' ) then 00220 fifo1_wr_en <= '1' after 1 ns; 00221 end if; 00222 end if; 00223 end process; 00224 00225 fifo1_wr_en_z <= fifo1_wr_en after 1 ns when rising_edge( clk ); 00226 00227 fifo1_wr <= fifo_wr_z and (fifo1_wr_en or fifo1_wr_en_z); 00228 00229 fifo1_cmpl: ctrl_fifo64x70st 00230 port map( 00231 clk => clk, 00232 rst => rstpz, 00233 din => fifo_din, 00234 wr_en => fifo1_wr, 00235 rd_en => fifo1_rd_x, 00236 dout => fifo1_dout, 00237 full => fifo1_full, 00238 empty => fifo1_empty, 00239 valid => fifo1_valid, 00240 prog_full => fifo1_paf, 00241 prog_empty => fifo1_pae 00242 ); 00243 00244 00245 00246 fifo1_rd_x <= fifo1_rd and ( not ( data_rx_we_en and not fifo1_dout(65) ) ); 00247 00248 reg_access.adr <= tlp_dw2; 00249 00250 reg_access.data( 7 downto 0 ) <= tlp_dw3( 31 downto 24 ); 00251 reg_access.data( 15 downto 8 ) <= tlp_dw3( 23 downto 16 ); 00252 reg_access.data( 23 downto 16 ) <= tlp_dw3( 15 downto 8 ); 00253 reg_access.data( 31 downto 24 ) <= tlp_dw3( 7 downto 0 ); 00254 00255 reg_access.req_wr(0) <=request_reg_wr and bar(0); 00256 reg_access.req_wr(1) <=request_reg_wr and bar(1); 00257 reg_access.req_rd(0) <=request_reg_rd and ( bar(0) or ( not (bar(0) or bar(1)) ) ); 00258 reg_access.req_rd(1) <=request_reg_rd and bar(1); 00259 00260 bar(0) <= fifo0_dout(68); 00261 bar(1) <= fifo0_dout(69); 00262 00263 rx_tx_engine.request_reg_wr <= request_reg_wr; 00264 rx_tx_engine.request_reg_rd <= request_reg_rd; 00265 rx_tx_engine.request_tag <= tlp_dw1( 15 downto 8 ); 00266 rx_tx_engine.request_tc <= tlp_dw0( 22 downto 20 ); 00267 rx_tx_engine.request_attr <= tlp_dw0( 7 downto 4 ); 00268 rx_tx_engine.request_id <= tlp_dw1( 31 downto 16 ); 00269 rx_tx_engine.lower_adr <= tlp_dw2( 6 downto 2 ); 00270 00271 pr_stp: process( clk ) begin 00272 if( rising_edge( clk ) ) then 00273 00274 case( stp ) is 00275 when s0 => 00276 if( fifo0_empty='0' ) then 00277 stp <= s1 after 1 ns; 00278 end if; 00279 request_reg_wr <= '0' after 1 ns; 00280 request_reg_rd <= '0' after 1 ns; 00281 fifo0_rd <= '0' after 1 ns; 00282 00283 when s1 => 00284 stp <= s2 after 1 ns; 00285 fifo0_rd <= '1' after 1 ns; 00286 00287 when s2 => 00288 stp <= s3 after 1 ns; 00289 fifo0_rd <= '0' after 1 ns; 00290 00291 when s3 => 00292 tlp_dw0 <= fifo0_dout( 63 downto 32 ) after 1 ns; 00293 tlp_dw1 <= fifo0_dout( 31 downto 0 ) after 1 ns; 00294 if( fifo0_empty='0' ) then 00295 stp <= s31 after 1 ns; 00296 end if; 00297 00298 when s31 => 00299 fifo0_rd <= '1' after 1 ns; 00300 stp <= s32 after 1 ns; 00301 00302 when s32 => 00303 fifo0_rd <= '0' after 1 ns; 00304 stp <= s4 after 1 ns; 00305 00306 when s4 => 00307 tlp_dw2 <= fifo0_dout( 63 downto 32 ) after 1 ns; 00308 tlp_dw3 <= fifo0_dout( 31 downto 0 ) after 1 ns; 00309 00310 if( tlp_dw0(30)='1' ) then 00311 request_reg_wr <= '1' after 1 ns; 00312 else 00313 request_reg_rd <= '1' after 1 ns; 00314 end if; 00315 stp <= s5 after 1 ns; 00316 00317 when s5 => 00318 if( tx_rx_engine.complete_reg='1' ) then 00319 stp <= s0 after 1 ns; 00320 end if; 00321 00322 end case; 00323 00324 00325 00326 if( rstpz='1' ) then 00327 stp <= s0 after 1 ns; 00328 end if; 00329 00330 end if; 00331 end process; 00332 00333 00334 pr_stf: process( clk ) begin 00335 00336 if( rising_edge( clk ) ) then 00337 00338 case( stf ) is 00339 00340 when s0 => 00341 --if( fifo1_empty='0' ) then 00342 if( fifo1_pae='0' ) then 00343 stf <= s1 after 1 ns; 00344 end if; 00345 fifo1_rd <= '0' after 1 ns; 00346 data_rx_we_en <= '0' after 1 ns; 00347 00348 when s1 => 00349 fifo1_rd <= '1' after 1 ns; 00350 stf <= s2 after 1 ns; 00351 00352 when s2 => 00353 stf <= s3 after 1 ns; 00354 00355 when s3 => 00356 tlp_cp_dw0 <= fifo1_dout( 63 downto 32 ) after 1 ns; 00357 tlp_cp_dw1 <= fifo1_dout( 31 downto 0 ) after 1 ns; 00358 fifo1_rd <= '0' after 1 ns; 00359 stf <= s4 after 1 ns; 00360 00361 when s4 => 00362 tlp_cp_dw2 <= fifo1_dout( 63 downto 32 ) after 1 ns; 00363 tlp_cp_dw3 <= fifo1_dout( 31 downto 0 ) after 1 ns; 00364 if( tlp_cp_dw0( 30 )='1' ) then 00365 stf <= s5 after 1 ns; -- есть данные -- 00366 else 00367 stf <= s6 after 1 ns; -- нет данных -- 00368 end if; 00369 00370 00371 when s5 => 00372 00373 if( fifo1_dout(65)='0' and fifo1_valid='1' ) then 00374 stf <= s6 after 1 ns; 00375 fifo1_rd <= '0' after 1 ns; 00376 data_rx_we_en <= '0' after 1 ns; 00377 else 00378 fifo1_rd <= '1' after 1 ns; 00379 data_rx_we_en <= '1' after 1 ns; 00380 end if; 00381 00382 when s6 => 00383 stf <= s0 after 1 ns; 00384 00385 00386 00387 end case; 00388 00389 if( rstpz='1' ) then 00390 stf <= s0 after 1 ns; 00391 end if; 00392 00393 end if; 00394 00395 00396 end process; 00397 00398 data_rx_we <= fifo1_valid and data_rx_we_en; 00399 00400 data_lrx <= fifo1_dout( 31 downto 0 ) after 1 ns when rising_edge( clk ) and fifo1_valid='1'; 00401 data_hrx <= fifo1_dout( 63 downto 32 ); 00402 00403 data_rx( 32+31 downto 32+24 ) <= data_hrx( 7 downto 0 ); 00404 data_rx( 32+23 downto 32+16 ) <= data_hrx( 15 downto 8 ); 00405 data_rx( 32+15 downto 32+8 ) <= data_hrx( 23 downto 16 ); 00406 data_rx( 32+7 downto 32+0 ) <= data_hrx( 31 downto 24 ); 00407 00408 00409 data_rx( 31 downto 24 ) <= data_lrx( 7 downto 0 ); 00410 data_rx( 23 downto 16 ) <= data_lrx( 15 downto 8 ); 00411 data_rx( 15 downto 8 ) <= data_lrx( 23 downto 16 ); 00412 data_rx( 7 downto 0 ) <= data_lrx( 31 downto 24 ); 00413 00414 pr_adr_cnt: process( clk ) begin 00415 if( rising_edge( clk ) ) then 00416 if( stf/=s5 ) then 00417 adr_cnt <= "0000" after 1 ns; 00418 elsif( data_rx_we='1' ) then 00419 adr_cnt( 2 downto 0 ) <= adr_cnt( 2 downto 0 ) + 1 after 1 ns; 00420 if( adr_cnt( 2 downto 0 )="111" ) then 00421 adr_cnt( 3 ) <= '1' after 1 ns; 00422 end if; 00423 end if; 00424 end if; 00425 end process; 00426 00427 adr_rx( 2 downto 0 ) <= adr_cnt( 2 downto 0 ); 00428 adr_rx( 3 ) <= tlp_cp_dw2(6) or adr_cnt( 3 ); 00429 adr_rx( 8 downto 4 ) <= tlp_cp_dw2( 12 downto 8 ); 00430 00431 rx_ext_fifo.adr <= adr_rx after 1 ns when rising_edge( clk ); 00432 rx_ext_fifo.data <= data_rx after 1 ns when rising_edge( clk ); 00433 rx_ext_fifo.data_we <= data_rx_we after 1 ns when rising_edge( clk ); 00434 00435 rx_tx_engine.complete_we <= data_rx_we after 1 ns when rising_edge( clk ); 00436 00437 end core64_rx_engine;