DS_DMA
pcie_src/pcie_core64_m1/pcie_fifo_ext/ctrl_ram_cmd_pb.vhd
00001 -------------------------------------------------------------------------------
00002 --
00003 -- Title       : ctrl_ram_cmd_pb
00004 -- Author      : Dmitry Smekhov
00005 -- Company     : Instrumental Systems
00006 -- E-mail      : dsmv@insys.ru
00007 --
00008 -- Version     : 1.0
00009 --
00010 -------------------------------------------------------------------------------
00011 --
00012 -- Description : Узел управления запросами к шине PLD_BUS
00013 --
00014 -------------------------------------------------------------------------------
00015 
00016 
00017 
00018 library ieee;
00019 use ieee.std_logic_1164.all;   
00020 
00021 package ctrl_ram_cmd_pb_pkg is
00022 
00023 component ctrl_ram_cmd_pb is
00024         port(
00025                 ---- Global ----
00026                 reset                           : in std_logic;         -- 0 - сброс
00027                 clk                                     : in std_logic;         --! Тактовая частота ядра - 250 МГц
00028                 aclk                            : in std_logic;         --! Тактовая частота локальной шины - 266 МГц
00029                 
00030                 act                                     : in std_logic;         -- 1 - разрешение цикла обработки
00031                 rdy                                     : out std_logic;        -- 1 - завершение цикла обработки
00032                 
00033                 flag_data                       : in  std_logic_vector( 1 downto 0 );   -- 1 - наличие данных в блоке
00034                 
00035                 flag_set                        : out std_logic_vector( 1 downto 0 );   -- 1 - установка флага наличия данных
00036                 flag_clr                        : out std_logic_vector( 1 downto 0 );   -- 1 - сброс флага наличия данных
00037                 next_block                      : in  std_logic;        -- 1 - признак достижения блока 4 килобайта
00038                 adr_hi_wr                       : out std_logic;        -- 1 - увеличение старших разрядов адреса для блока
00039                 
00040                 reg_ctrl                        : in std_logic_vector( 7 downto 0 ); -- регистр управления
00041                 
00042                 dmar                            : in  std_logic;        -- 1 - запрос DMA                                   
00043                 
00044                 pf_cb                           : out std_logic;        -- номер текущего блока для обмена с шиной
00045                 pf_dma_wr_rdy           : out std_logic;        -- 1 - готовность передать 512 слов
00046                 pf_dma_rd_rdy           : out std_logic;        -- 1 - готовность принять 512 слов
00047                 
00048                 pf_ram_rd                       : in  std_logic;        -- 1 - чтение данных из памяти
00049                 pf_repack_we            : in  std_logic         -- 1 - запись в память
00050                 
00051         
00052         );
00053 end component;
00054 
00055 end package;
00056 
00057 
00058 
00059 library ieee;
00060 use ieee.std_logic_1164.all;   
00061 use ieee.std_logic_arith.all;
00062 use ieee.std_logic_unsigned.all;
00063 
00064 entity ctrl_ram_cmd_pb is
00065         port(
00066                 ---- Global ----
00067                 reset                           : in std_logic;         -- 0 - сброс
00068                 clk                                     : in std_logic;         --! Тактовая частота ядра - 250 МГц
00069                 aclk                            : in std_logic;         --! Тактовая частота локальной шины - 266 МГц
00070                 
00071                 act                                     : in std_logic;         -- 1 - разрешение цикла обработки
00072                 rdy                                     : out std_logic;        -- 1 - завершение цикла обработки
00073                 
00074                 flag_data                       : in  std_logic_vector( 1 downto 0 );   -- 1 - наличие данных в блоке
00075                 
00076                 flag_set                        : out std_logic_vector( 1 downto 0 );   -- 1 - установка флага наличия данных
00077                 flag_clr                        : out std_logic_vector( 1 downto 0 );   -- 1 - сброс флага наличия данных
00078                 next_block                      : in  std_logic;        -- 1 - признак достижения блока 4 килобайта
00079                 adr_hi_wr                       : out std_logic;        -- 1 - увеличение старших разрядов адреса для блока
00080                 
00081                 reg_ctrl                        : in std_logic_vector( 7 downto 0 ); -- регистр управления
00082                 
00083                 dmar                            : in  std_logic;        -- 1 - запрос DMA                                   
00084                 
00085                 pf_cb                           : out std_logic;        -- номер текущего блока для обмена с шиной
00086                 pf_dma_wr_rdy           : out std_logic;        -- 1 - готовность передать 128 слов
00087                 pf_dma_rd_rdy           : out std_logic;        -- 1 - готовность принять 128 слов
00088                 
00089                 pf_ram_rd                       : in  std_logic;        -- 1 - чтение данных из памяти
00090                 pf_repack_we            : in  std_logic         -- 1 - запись в память
00091                 
00092         
00093         );
00094 end ctrl_ram_cmd_pb;
00095 
00096 
00097 architecture ctrl_ram_cmd_pb of ctrl_ram_cmd_pb is
00098 
00099 type  stp_type is ( s0, s2,  sr2, sr5, sr6, sw2, sw3 ); -- s1, sr0, sr1,
00100 signal  stp             : stp_type;
00101 
00102 signal  rst_p   : std_logic;             
00103 signal  rst_p0  : std_logic;             
00104 
00105 signal  cb              : std_logic;
00106 
00107 signal  block_rd_eot    : std_logic;
00108 signal  block_wr_eot    : std_logic;
00109 signal  pf_repack_we_z  : std_logic;
00110 signal  pf_ram_rd_z             : std_logic;
00111 
00112 signal  start_rd                : std_logic;
00113 signal  start_wr                : std_logic;   
00114 signal  dmari                   : std_logic;
00115 
00116 signal  start_rd0               : std_logic;
00117 signal  start_wr0               : std_logic;
00118 
00119 signal  start_rd1               : std_logic;
00120 signal  start_wr1               : std_logic;
00121 
00122 signal  flag0_set               : std_logic_vector( 1 downto 0 );
00123 signal  flag1_set               : std_logic_vector( 1 downto 0 );
00124 signal  flag2_set               : std_logic_vector( 1 downto 0 );
00125 
00126 signal  flag0_clr               : std_logic_vector( 1 downto 0 );
00127 signal  flag1_clr               : std_logic_vector( 1 downto 0 );
00128 signal  flag2_clr               : std_logic_vector( 1 downto 0 );
00129 
00130 
00131 attribute       tig                     : string;
00132 attribute       tig                     of flag2_set    : signal is "";
00133 attribute       tig                     of flag2_clr    : signal is "";
00134 attribute       tig                     of start_rd0    : signal is "";
00135 attribute       tig                     of start_wr0    : signal is "";
00136 
00137 begin
00138         
00139 rst_p0 <= (not reset) or reg_ctrl(4) after 1 ns when rising_edge( aclk );       
00140 rst_p <= rst_p0 after 1 ns when rising_edge( aclk );    
00141 
00142 pf_cb <= cb;                                            
00143 
00144 pf_repack_we_z <= pf_repack_we after 1 ns when rising_edge( aclk );
00145 block_rd_eot <= '1' when pf_repack_we='0' and pf_repack_we_z='1' else '0';
00146         
00147 pf_ram_rd_z <= pf_ram_rd after 1 ns when rising_edge( aclk );
00148 block_wr_eot <= '1' when pf_ram_rd='0' and pf_ram_rd_z='1' else '0';
00149         
00150 dmari <= dmar or not reg_ctrl(1);
00151 
00152 start_rd0 <= reg_ctrl(0) and reg_ctrl(2) and dmari and not flag_data( conv_integer(cb) ) after 1 ns when rising_edge( aclk );
00153 start_wr0 <= reg_ctrl(0) and (not reg_ctrl(2)) and dmari and flag_data( conv_integer(cb) ) after 1 ns when rising_edge( aclk ) ;
00154 
00155 start_rd1 <= start_rd0 after 1 ns when rising_edge( aclk );
00156 start_wr1 <= start_wr0 after 1 ns when rising_edge( aclk );
00157 
00158 start_rd <= act and start_rd1;
00159 start_wr <= act and start_wr1;
00160 
00161 pr_state: process( aclk ) begin
00162         if( rising_edge( aclk ) ) then
00163                 
00164                 case( stp ) is
00165                         
00166                         when s0 =>
00167                                 flag0_set(0) <= '0' after 1 ns;
00168                                 flag0_set(1) <= '0' after 1 ns;
00169                                 flag0_clr(0) <= '0' after 1 ns;
00170                                 flag0_clr(1) <= '0' after 1 ns;    
00171                                 adr_hi_wr <= '0' after 1 ns;
00172                                 
00173                                 pf_dma_wr_rdy <= '0' after 1 ns;                 
00174                                 pf_dma_rd_rdy <= '0' after 1 ns;
00175                                 
00176                                 rdy <= '0' after 1 ns;     
00177                                 if( start_rd='1' ) then
00178                                         pf_dma_rd_rdy <= '1' after  1 ns;
00179                                         stp <= sr2 after  1ns;
00180                                 elsif( start_wr='1' ) then
00181                                     pf_dma_wr_rdy <= '1' after 1 ns;             
00182                                         stp <= sw2 after 1 ns;
00183                                 elsif( act='1' ) then
00184                                         stp <= s2 after 1 ns;
00185                                 end if;
00186                         
00187 
00188                         
00189                         when s2 => --- Канал DMA выключен ----
00190                                 rdy <= '1' after 1 ns;
00191                                 --cb <= '0';
00192                                 if( act='0' ) then
00193                                         stp <= s0 after 1 ns;
00194                                 end if;
00195                 
00196 
00197 
00198                         when sr2 =>       
00199                                 if( pf_repack_we_z='1' ) then
00200                                         pf_dma_rd_rdy <= '0' after 1 ns;
00201                                 end if;
00202                                 if( block_rd_eot='1' ) then
00203                                         stp <= sr5 after 1 ns;
00204                                 end if;
00205                                 
00206                                 
00207                         when sr5 =>
00208                                 --flag_set(conv_integer(cb)) <= '1' after 1 ns;
00209                         
00210                                 flag0_set(0) <= next_block and not cb after 1 ns;
00211                                 flag0_set(1) <= next_block and cb after 1 ns;
00212                                 if( next_block='1' ) then
00213                                         cb <= not cb after 1 ns;
00214                                 end if;
00215                                 stp <= sr6 after 1 ns;          
00216                                 adr_hi_wr <= '1' after 1 ns;
00217 
00218                         when sr6 =>                                             
00219                                 adr_hi_wr <= '0' after 1 ns;
00220                                 flag0_set(0) <= '0' after 1 ns;
00221                                 flag0_set(1) <= '0' after 1 ns;
00222                                 flag0_clr(0) <= '0' after 1 ns;
00223                                 flag0_clr(1) <= '0' after 1 ns;
00224                                 rdy <= '1' after 1 ns;
00225                                 if( act='0' ) then
00226                                         stp <= s0 after 1 ns;
00227                                 end if;                                                                          
00228                                 
00229                         when sw2 =>
00230                                 if( pf_ram_rd='1' ) then
00231                                         pf_dma_wr_rdy <= '0' after  1 ns;
00232                                 end if;
00233                                 if( block_wr_eot='1' ) then
00234                                         stp <= sw3 after 1 ns;
00235                                 end if;
00236                                 
00237                         when sw3 =>
00238                                 flag0_clr(0) <= next_block and not cb after 1 ns;
00239                                 flag0_clr(1) <= next_block and cb after 1 ns;
00240                                 if( next_block='1' ) then
00241                                         cb <= not cb after 1 ns;
00242                                 end if;                 
00243                                 stp <= sr6 after  1 ns;
00244                                 adr_hi_wr <= '1' after 1 ns;
00245                                 
00246                         
00247                         
00248                 end case;                                                                 
00249                 
00250                 
00251                 if( rst_p='1' ) then
00252                         stp <= s0;              
00253                         cb <= '0';
00254                 end if;
00255                 
00256                 
00257         end if;
00258 end process;
00259 
00260 gen_flag: for ii in 0 to 1 generate
00261 
00262 pr_flag1_set: process( flag0_set(ii), clk ) begin
00263         
00264         if( flag0_set(ii)='1' ) then
00265                 flag1_set(ii) <= '1' after 1 ns;
00266         elsif( rising_edge( clk ) ) then
00267                 if( flag2_set(ii)='1' or rst_p='1' ) then
00268                         flag1_set(ii) <= '0' after 1 ns;
00269                 end if;
00270         end if;
00271         
00272 end process;
00273 
00274 pr_flag1_clr: process( flag0_clr(ii), clk ) begin
00275         
00276         if( flag0_clr(ii)='1' ) then
00277                 flag1_clr(ii) <= '1' after 1 ns;
00278         elsif( rising_edge( clk ) ) then
00279                 if( flag2_clr(ii)='1' or rst_p='1' ) then
00280                         flag1_clr(ii) <= '0' after 1 ns;
00281                 end if;
00282         end if;
00283         
00284 end process;
00285 
00286 end generate;
00287 
00288 flag2_set <= flag1_set after 1 ns when rising_edge( clk );
00289 flag2_clr <= flag1_clr after 1 ns when rising_edge( clk );
00290 
00291 flag_set <= flag1_set;
00292 flag_clr <= flag1_clr;
00293 
00294 
00295 end ctrl_ram_cmd_pb;