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