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