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