DS_DMA
|
00001 ------------------------------------------------------------------------------- 00002 -- 00003 -- Title : ctrl_ram_cmd 00004 -- Author : Dmitry Smekhov 00005 -- Company : Instrumental Systems 00006 -- E-mail : dsmv@insys.ru 00007 -- 00008 -- Version : 1.2 00009 -- 00010 ------------------------------------------------------------------------------- 00011 -- 00012 -- Description : Узел управления памятью 00013 -- 00014 ------------------------------------------------------------------------------- 00015 -- 00016 -- Version 1.2 05.04.2010 00017 -- Добавлен параметр is_dsp48 - разрешение использования 00018 -- блоков DSP48 00019 -- 00020 ------------------------------------------------------------------------------- 00021 -- 00022 -- Version 1.1 02.09.2009 00023 -- Исправлен сброс ch1_adr_hi 00024 -- 00025 ------------------------------------------------------------------------------- 00026 00027 library ieee; 00028 use ieee.std_logic_1164.all; 00029 00030 package ctrl_ram_cmd_pkg is 00031 00032 component ctrl_ram_cmd is 00033 generic( 00034 is_dsp48 : in integer:=1 -- 1 - использовать DSP48, 0 - не использовать DSP48 00035 ); 00036 port( 00037 ---- Global ---- 00038 reset : in std_logic; -- 0 - сброс 00039 clk : in std_logic; --! Тактовая частота ядра - 250 МГц 00040 aclk : in std_logic; --! Тактовая частота локальной шины - 266 МГц 00041 00042 ---- Picoblaze ---- 00043 dma_chn : in std_logic; -- номер канала DMA 00044 reg_ch0_ctrl : in std_logic_vector( 7 downto 0 ); -- регистр управления 00045 reg_ch1_ctrl : in std_logic_vector( 7 downto 0 ); -- регистр управления 00046 reg_write_E0 : in std_logic; -- 1 - смена блока памяти 00047 dma0_transfer_rdy : out std_logic; -- 1 - блок памяти готов к обмену 00048 dma1_transfer_rdy : out std_logic; -- 1 - блок памяти готов к обмену 00049 00050 ---- PLB_BUS ---- 00051 dmar0 : in std_logic; -- 1 - запрос DMA 0 00052 dmar1 : in std_logic; -- 1 - запрос DMA 1 00053 request_wr : out std_logic; --! 1 - запрос на запись в регистр 00054 request_rd : out std_logic; --! 1 - запрос на чтение из регистра 00055 allow_wr : in std_logic; --! 1 - разрешение записи 00056 00057 00058 pf_repack_we : in std_logic; -- 1 - запись в память 00059 pf_ram_rd_out : out std_logic; -- 1 - чтение из памяти 00060 00061 ---- Память ---- 00062 ram_adra_a9 : out std_logic; -- разряд 9 адреса памяти 00063 ram_adrb : out std_logic_vector( 10 downto 0 ) 00064 00065 ); 00066 00067 end component; 00068 00069 end package; 00070 00071 00072 library ieee; 00073 use ieee.std_logic_1164.all; 00074 use ieee.std_logic_arith.all; 00075 use ieee.std_logic_unsigned.all; 00076 00077 library unisim; 00078 use unisim.vcomponents.all; 00079 00080 00081 use work.ctrl_ram_cmd_pb_pkg.all; 00082 00083 entity ctrl_ram_cmd is 00084 generic( 00085 is_dsp48 : in integer:=1 -- 1 - использовать DSP48, 0 - не использовать DSP48 00086 ); 00087 port( 00088 ---- Global ---- 00089 reset : in std_logic; -- 0 - сброс 00090 clk : in std_logic; --! Тактовая частота ядра - 250 МГц 00091 aclk : in std_logic; --! Тактовая частота локальной шины - 266 МГц 00092 00093 ---- Picoblaze ---- 00094 dma_chn : in std_logic; -- номер канала DMA 00095 reg_ch0_ctrl : in std_logic_vector( 7 downto 0 ); -- регистр управления 00096 reg_ch1_ctrl : in std_logic_vector( 7 downto 0 ); -- регистр управления 00097 reg_write_E0 : in std_logic; -- 1 - смена блока памяти 00098 dma0_transfer_rdy : out std_logic; -- 1 - блок памяти готов к обмену 00099 dma1_transfer_rdy : out std_logic; -- 1 - блок памяти готов к обмену 00100 00101 ---- PLB_BUS ---- 00102 dmar0 : in std_logic; -- 1 - запрос DMA 0 00103 dmar1 : in std_logic; -- 1 - запрос DMA 1 00104 request_wr : out std_logic; --! 1 - запрос на запись в регистр 00105 request_rd : out std_logic; --! 1 - запрос на чтение из регистра 00106 allow_wr : in std_logic; --! 1 - разрешение записи 00107 00108 pf_repack_we : in std_logic; -- 1 - запись в память 00109 pf_ram_rd_out : out std_logic; -- 1 - чтение из памяти 00110 00111 ---- Память ---- 00112 ram_adra_a9 : out std_logic; -- разряд 9 адреса памяти 00113 ram_adrb : out std_logic_vector( 10 downto 0 ) 00114 00115 ); 00116 00117 end ctrl_ram_cmd; 00118 00119 00120 architecture ctrl_ram_cmd of ctrl_ram_cmd is 00121 00122 signal pb_current_block: std_logic_vector( 1 downto 0 ); 00123 signal flag_data : std_logic_vector( 3 downto 0 ); 00124 00125 signal cb : std_logic; 00126 00127 signal pb_flag_set : std_logic_vector( 3 downto 0 ); 00128 signal pb_flag_clr : std_logic_vector( 3 downto 0 ); 00129 00130 signal pf_flag_set : std_logic_vector( 3 downto 0 ); 00131 signal pf_flag_clr : std_logic_vector( 3 downto 0 ); 00132 00133 signal pb_fclr : std_logic; 00134 signal pb_fset : std_logic; 00135 00136 signal reg_write_E0_z : std_logic; 00137 signal reg_write_E0_z1 : std_logic; 00138 00139 signal pf_chn : std_logic; 00140 signal pf0_act : std_logic; 00141 signal pf0_rdy : std_logic; 00142 signal pf1_act : std_logic; 00143 signal pf1_rdy : std_logic; 00144 00145 type stp_type is ( s0, s1, s2, s3 ); 00146 signal stp : stp_type; 00147 00148 signal rst_p : std_logic; 00149 signal rst_p0 : std_logic; 00150 00151 signal pf0_cb : std_logic; 00152 signal pf0_dma_wr_rdy : std_logic; 00153 signal pf0_dma_rd_rdy : std_logic; 00154 00155 signal pf1_cb : std_logic; 00156 signal pf1_dma_wr_rdy : std_logic; 00157 signal pf1_dma_rd_rdy : std_logic; 00158 00159 signal ram0_transfer_rdy : std_logic; 00160 signal ram1_transfer_rdy : std_logic; 00161 00162 signal port_a : std_logic_vector( 17 downto 0 ); 00163 signal port_b : std_logic_vector( 17 downto 0 ); 00164 signal port_c : std_logic_vector( 47 downto 0 ); 00165 signal port_p : std_logic_vector( 47 downto 0 ); 00166 signal opmode : std_logic_vector( 6 downto 0 ); 00167 signal carry : std_logic; 00168 signal cnt_rstp : std_logic; 00169 00170 signal ch0_adr_hi : std_logic_vector( 1 downto 0 ); 00171 signal ch1_adr_hi : std_logic_vector( 1 downto 0 ); 00172 signal ch0_next_block : std_logic; 00173 signal ch1_next_block : std_logic; 00174 signal ch0_adr_hi_wr : std_logic; 00175 signal ch1_adr_hi_wr : std_logic; 00176 00177 signal pf_ram_rd : std_logic; 00178 signal pf_dma_wr_rdy : std_logic; 00179 signal pf_dma_rd_rdy : std_logic; 00180 00181 begin 00182 00183 cb <= pb_current_block( conv_integer( dma_chn ) ); 00184 ram_adra_a9 <= cb; 00185 00186 reg_write_E0_z <= reg_write_E0 after 1 ns when rising_edge( clk ); 00187 reg_write_E0_z1 <= reg_write_E0_z after 1 ns when rising_edge( clk ); 00188 00189 00190 pb_flag_clr(0) <= reg_ch0_ctrl(4) or ( reg_write_E0_z and reg_ch0_ctrl(2) and not dma_chn and not pb_current_block(0) ) after 1 ns when rising_edge( clk ); 00191 pb_flag_clr(1) <= reg_ch0_ctrl(4) or ( reg_write_E0_z and reg_ch0_ctrl(2) and not dma_chn and pb_current_block(0) ) after 1 ns when rising_edge( clk ); 00192 pb_flag_clr(2) <= reg_ch1_ctrl(4) or ( reg_write_E0_z and reg_ch1_ctrl(2) and dma_chn and not pb_current_block(1) ) after 1 ns when rising_edge( clk ); 00193 pb_flag_clr(3) <= reg_ch1_ctrl(4) or ( reg_write_E0_z and reg_ch1_ctrl(2) and dma_chn and pb_current_block(1) ) after 1 ns when rising_edge( clk ); 00194 00195 pb_flag_set(0) <= reg_write_E0_z and not reg_ch0_ctrl(2) and not dma_chn and not pb_current_block(0) after 1 ns when rising_edge( clk ); 00196 pb_flag_set(1) <= reg_write_E0_z and not reg_ch0_ctrl(2) and not dma_chn and pb_current_block(0) after 1 ns when rising_edge( clk ); 00197 pb_flag_set(2) <= reg_write_E0_z and not reg_ch1_ctrl(2) and dma_chn and not pb_current_block(1) after 1 ns when rising_edge( clk ); 00198 pb_flag_set(3) <= reg_write_E0_z and not reg_ch1_ctrl(2) and dma_chn and pb_current_block(1) after 1 ns when rising_edge( clk ); 00199 00200 00201 pr_current_block0: process( clk ) begin 00202 if( rising_edge( clk ) ) then 00203 if( reg_ch0_ctrl(4)='1' ) then 00204 pb_current_block(0) <= '0' after 1 ns; 00205 elsif( reg_write_E0_z1='1' and dma_chn='0' ) then 00206 pb_current_block(0) <= not pb_current_block(0) after 1 ns; 00207 end if; 00208 end if; 00209 end process; 00210 00211 pr_current_block1: process( clk ) begin 00212 if( rising_edge( clk ) ) then 00213 if( reg_ch1_ctrl(4)='1' ) then 00214 pb_current_block(1) <= '0' after 1 ns; 00215 elsif( reg_write_E0_z1='1' and dma_chn='1' ) then 00216 pb_current_block(1) <= not pb_current_block(1) after 1 ns; 00217 end if; 00218 end if; 00219 end process; 00220 00221 00222 00223 gen_flag: for ii in 0 to 3 generate 00224 00225 process( clk ) begin 00226 if( rising_edge( clk ) ) then 00227 if( pb_flag_clr(ii)='1' or pf_flag_clr(ii)='1' or rst_p='1' ) then 00228 flag_data(ii) <= '0' after 1 ns; 00229 elsif( pb_flag_set(ii)='1' or pf_flag_set(ii)='1' ) then 00230 flag_data(ii) <= '1' after 1 ns; 00231 end if; 00232 end if; 00233 end process; 00234 00235 00236 end generate; 00237 00238 00239 ---- Формирование готовности блока к обмену ---- 00240 pr0_transfer_rdy: process( clk ) begin 00241 if( rising_edge( clk ) ) then 00242 if( reg_ch0_ctrl(2)='1' and flag_data( conv_integer(pb_current_block(0)) )='1' ) then 00243 ram0_transfer_rdy <= reg_ch0_ctrl(0) and not reg_ch0_ctrl(3) after 1 ns; 00244 elsif( reg_ch0_ctrl(2)='0' and flag_data( conv_integer(pb_current_block(0)) )='0' ) then 00245 ram0_transfer_rdy <= reg_ch0_ctrl(0) and not reg_ch0_ctrl(3) after 1 ns; 00246 else 00247 ram0_transfer_rdy <= '0' after 1 ns; 00248 end if; 00249 end if; 00250 end process; 00251 00252 pr1_transfer_rdy: process( clk ) begin 00253 if( rising_edge( clk ) ) then 00254 if( reg_ch1_ctrl(2)='1' and flag_data( 2+conv_integer(pb_current_block(1)) )='1' ) then 00255 ram1_transfer_rdy <= reg_ch1_ctrl(0) and not reg_ch1_ctrl(3) after 1 ns; 00256 elsif( reg_ch1_ctrl(2)='0' and flag_data( 2+conv_integer(pb_current_block(1)) )='0' ) then 00257 ram1_transfer_rdy <= reg_ch1_ctrl(0) and not reg_ch1_ctrl(3) after 1 ns; 00258 else 00259 ram1_transfer_rdy <= '0' after 1 ns; 00260 end if; 00261 end if; 00262 end process; 00263 00264 dma0_transfer_rdy <= ram0_transfer_rdy; 00265 dma1_transfer_rdy <= ram1_transfer_rdy; 00266 00267 00268 --ram_transfer_rdy <= (ram0_transfer_rdy and not dma_chn) or (ram1_transfer_rdy and dma_chn) after 1 ns 00269 -- when rising_edge( clk ); 00270 00271 ---- Перебор каналов DMA ---- 00272 00273 rst_p0 <= not reset after 1 ns when rising_edge( aclk ); 00274 rst_p <= rst_p0 after 1 ns when rising_edge( aclk ); 00275 00276 pr_state: process( aclk ) begin 00277 if( rising_edge( aclk ) ) then 00278 00279 case( stp ) is 00280 when s0 => 00281 cnt_rstp <= '0' after 1 ns; 00282 pf_chn <= '0' after 1 ns; 00283 pf0_act <= '1' after 1 ns; 00284 pf1_act <= '0' after 1 ns; 00285 if( pf0_rdy='1' ) then 00286 stp <= s1 after 1 ns; 00287 end if; 00288 00289 when s1 => 00290 cnt_rstp <= '1' after 1 ns; 00291 pf0_act <= '0' after 1 ns; 00292 if( pf0_rdy='0' ) then 00293 stp <= s2 after 1 ns; 00294 end if; 00295 00296 when s2 => 00297 cnt_rstp <= '0' after 1 ns; 00298 pf_chn <= '1' after 1 ns; 00299 pf1_act <= '1' after 1 ns; 00300 if( pf1_rdy='1' ) then 00301 stp <= s3 after 1 ns; 00302 end if; 00303 00304 when s3 => 00305 cnt_rstp <= '1' after 1 ns; 00306 pf1_act <= '0' after 1 ns; 00307 if( pf1_rdy='0' ) then 00308 stp <= s0 after 1 ns; 00309 end if; 00310 00311 end case; 00312 00313 if( rst_p='1' ) then 00314 stp <= s0 after 1 ns; 00315 pf0_act <= '0' after 1 ns; 00316 cnt_rstp <= '1' after 1 ns; 00317 00318 end if; 00319 00320 end if; 00321 end process; 00322 00323 00324 00325 cmd0: ctrl_ram_cmd_pb 00326 port map( 00327 ---- Global ---- 00328 reset => reset, -- 0 - сброс 00329 clk => clk, -- тактовая частота 250 МГц 00330 aclk => aclk, -- тактовая частота 266 МГц 00331 00332 act => pf0_act, -- 1 - разрешение цикла обработки 00333 rdy => pf0_rdy, -- 1 - завершение цикла обработки 00334 00335 flag_data => flag_data( 1 downto 0 ), -- 1 - наличие данных в блоке 00336 00337 flag_set => pf_flag_set( 1 downto 0 ), -- 1 - установка флага наличия данных 00338 flag_clr => pf_flag_clr( 1 downto 0 ), -- 1 - сброс флага наличия данных 00339 next_block => ch0_next_block, -- 1 - признак достижения блока 4 килобайта 00340 adr_hi_wr => ch0_adr_hi_wr, -- 1 - увеличение старших разрядов адреса для блока 00341 00342 reg_ctrl => reg_ch0_ctrl( 7 downto 0 ), -- регистр управления 00343 00344 dmar => dmar0, -- 1 - запрос DMA 00345 00346 pf_cb => pf0_cb, -- номер текущего блока для обмена с шиной 00347 pf_dma_wr_rdy => pf0_dma_wr_rdy, -- 1 - готовность передать 128 слов 00348 pf_dma_rd_rdy => pf0_dma_rd_rdy, -- 1 - готовность принять 128 слов 00349 00350 pf_ram_rd => pf_ram_rd, -- 1 - чтение данных из памяти 00351 pf_repack_we => pf_repack_we-- 1 - запись в память 00352 ); 00353 00354 cmd1: ctrl_ram_cmd_pb 00355 port map( 00356 ---- Global ---- 00357 reset => reset, -- 0 - сброс 00358 clk => clk, -- тактовая частота 250 МГц 00359 aclk => aclk, -- тактовая частота 266 МГц 00360 00361 act => pf1_act, -- 1 - разрешение цикла обработки 00362 rdy => pf1_rdy, -- 1 - завершение цикла обработки 00363 00364 flag_data => flag_data( 3 downto 2 ), -- 1 - наличие данных в блоке 00365 00366 flag_set => pf_flag_set( 3 downto 2 ), -- 1 - установка флага наличия данных 00367 flag_clr => pf_flag_clr( 3 downto 2 ), -- 1 - сброс флага наличия данных 00368 next_block => ch1_next_block, -- 1 - признак достижения блока 4 килобайта 00369 adr_hi_wr => ch1_adr_hi_wr, -- 1 - увеличение старших разрядов адреса для блока 00370 00371 reg_ctrl => reg_ch1_ctrl( 7 downto 0 ), -- регистр управления 00372 00373 dmar => dmar1, -- 1 - запрос DMA 00374 00375 pf_cb => pf1_cb, -- номер текущего блока для обмена с шиной 00376 pf_dma_wr_rdy => pf1_dma_wr_rdy, -- 1 - готовность передать 128 слов 00377 pf_dma_rd_rdy => pf1_dma_rd_rdy, -- 1 - готовность принять 128 слов 00378 00379 pf_ram_rd => pf_ram_rd, -- 1 - чтение данных из памяти 00380 pf_repack_we => pf_repack_we-- 1 - запись в память 00381 ); 00382 00383 pf_dma_wr_rdy <= pf0_dma_wr_rdy or pf1_dma_wr_rdy; 00384 pf_dma_rd_rdy <= pf0_dma_rd_rdy or pf1_dma_rd_rdy; 00385 00386 request_wr <= pf_dma_wr_rdy; 00387 request_rd <= pf_dma_rd_rdy; 00388 00389 ram_adrb(10) <= pf_chn; 00390 ram_adrb(9) <= pf0_cb when pf_chn='0' else pf1_cb; 00391 00392 --ram_adrb( 8 downto 7 ) <= ch0_adr_hi when pf_chn='0' else ch1_adr_hi; 00393 -- 00394 --ram_adrb( 6 downto 0 ) <= port_p( 6 downto 0 ) after 1 ns; 00395 00396 ram_adrb( 8 downto 0 ) <= port_p( 8 downto 0 ) after 1 ns; 00397 00398 opmode <= "0100000"; 00399 carry <= pf_repack_we or pf_ram_rd; 00400 00401 pr_pf_ram_rd: process( aclk ) begin 00402 if( rising_edge( aclk ) ) then 00403 if( cnt_rstp='1' or port_p( 8 downto 0 )="111111111" ) then 00404 pf_ram_rd <= '0' after 1 ns; 00405 elsif( pf_dma_wr_rdy='1' and allow_wr='1' ) then 00406 pf_ram_rd <= '1' after 1 ns; 00407 end if; 00408 end if; 00409 end process; 00410 00411 pf_ram_rd_out <= pf_ram_rd; 00412 00413 00414 port_b <= x"0000" & "00"; 00415 port_a <= x"0000" & "00"; 00416 00417 port_c <= port_p; 00418 00419 00420 gen_dsp48: if( is_dsp48=1 ) generate 00421 00422 dsp: DSP48 00423 generic map( 00424 00425 AREG => 1, 00426 B_INPUT => "DIRECT", 00427 BREG => 1, 00428 CARRYINREG => 0, 00429 CARRYINSELREG => 1, 00430 CREG => 1, 00431 LEGACY_MODE => "NONE", 00432 MREG => 1, 00433 OPMODEREG => 1, 00434 PREG => 1, 00435 SUBTRACTREG => 0 00436 ) 00437 00438 port map( 00439 --BCOUT : out std_logic_vector(17 downto 0); 00440 P => port_p, 00441 --PCOUT : out std_logic_vector(47 downto 0); 00442 00443 A => port_a, 00444 B => port_b, 00445 BCIN => (others=>'0'), 00446 C => port_c, 00447 CARRYIN => carry, 00448 CARRYINSEL => "00", 00449 CEA => '1', 00450 CEB => '1', 00451 CEC => '1', 00452 CECARRYIN => '1', 00453 CECINSUB => '1', 00454 CECTRL => '1', 00455 CEM => '1', 00456 CEP => '1', 00457 CLK => aclk, 00458 OPMODE => opmode, 00459 PCIN => (others=>'0'), 00460 RSTA => '0', 00461 RSTB => '0', 00462 RSTC => '0', 00463 RSTCARRYIN => '0', 00464 RSTCTRL => '0', 00465 RSTM => '0', 00466 RSTP => cnt_rstp, 00467 SUBTRACT => '0' 00468 ); 00469 00470 end generate; 00471 00472 gen_ndsp48: if( is_dsp48=0 ) generate 00473 00474 port_p( 47 downto 9 ) <= (others=>'0'); 00475 00476 pr_dsp: process( clk ) begin 00477 if( rising_edge( clk ) ) then 00478 if( cnt_rstp='1' ) then 00479 port_p( 8 downto 0 ) <= (others=>'0' ) after 1 ns; 00480 elsif( carry='1' ) then 00481 port_p( 8 downto 0 ) <= port_p( 8 downto 0 ) + 1 after 1 ns; 00482 end if; 00483 end if; 00484 end process; 00485 00486 end generate; 00487 00488 00489 pr_ch0_adr_hi: process( clk ) begin 00490 if( rising_edge( clk ) ) then 00491 if( reset='0' or reg_ch0_ctrl(4)='1' ) then 00492 ch0_adr_hi <= "00" after 1 ns; 00493 elsif( ch0_adr_hi_wr='1' ) then 00494 ch0_adr_hi <= ch0_adr_hi + 1 after 1 ns; 00495 end if; 00496 end if; 00497 end process; 00498 00499 pr_ch1_adr_hi: process( clk ) begin 00500 if( rising_edge( clk ) ) then 00501 if( reset='0' or reg_ch1_ctrl(4)='1' ) then 00502 ch1_adr_hi <= "00" after 1 ns; 00503 elsif( ch1_adr_hi_wr='1' ) then 00504 ch1_adr_hi <= ch1_adr_hi + 1 after 1 ns; 00505 end if; 00506 end if; 00507 end process; 00508 00509 --ch0_next_block <= ch0_adr_hi(0) and ch0_adr_hi(1); 00510 --ch1_next_block <= ch1_adr_hi(0) and ch1_adr_hi(1); 00511 00512 ch0_next_block <= '1'; 00513 ch1_next_block <= '1'; 00514 00515 00516 end ctrl_ram_cmd;