DS_DMA
pcie_src/pcie_core64_m1/pcie_ctrl/core64_rx_engine.vhd
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;