DS_DMA
|
00001 ------------------------------------------------------------------------------- 00002 -- 00003 -- Title : ctrl_ext_descriptor 00004 -- Author : Dmitry Smekhov 00005 -- Company : Instrumental Systems 00006 -- E-mail : dsmv@insys.ru 00007 -- 00008 -- Version : 1.3 00009 -- 00010 ------------------------------------------------------------------------------- 00011 -- 00012 -- Description : Память дескрипторов 00013 -- 00014 -- Регистры для записи 00015 -- 0 - регистр управления 00016 -- 0: 1 - разрешение записи дескриптора 00017 -- 1: 1 - сброс адреса 00018 -- 2: 00019 -- 4 - Запись в регистр приводит к смене адреса 00020 -- 8 - регистр записи данных в память дескриптора 00021 -- последовательно записывается три байта адреса, 00022 -- которые помещаются по текущему адресу памяти. 00023 -- Первым записывается страший байт адреса. 00024 -- 00025 -- 00026 -- 00027 -- Регистры для чтения 00028 -- 0 - DESCRIPTOR_CMD 00029 -- командное слово дескриптора 00030 -- 00031 -- Поле регистра состояния: 00032 -- 0: 1 - блок дескрипторов правильный 00033 -- 1: 0 - наличие следующего дескриптора 00034 -- 00035 -- 00036 ------------------------------------------------------------------------------- 00037 -- 00038 -- Version : 1.3 26.01.2011 00039 -- Добавлена запись 40-битного начального адреса дескриптора 00040 -- 00041 ------------------------------------------------------------------------------- 00042 -- 00043 -- Version : 1.2 05.04.2010 00044 -- Добавлен параметр is_dsp48 - разрешение использования 00045 -- блоков DSP48 00046 -- 00047 ------------------------------------------------------------------------------- 00048 -- 00049 -- Version : 1.1 26.01.2010 00050 -- Используется 40-битный адрес на шине PCI 00051 -- 00052 ------------------------------------------------------------------------------- 00053 00054 00055 library ieee; 00056 use ieee.std_logic_1164.all; 00057 00058 package ctrl_ext_descriptor_pkg is 00059 00060 component ctrl_ext_descriptor is 00061 generic( 00062 is_dsp48 : in integer:=1 -- 1 - использовать DSP48, 0 - не использовать DSP48 00063 ); 00064 port( 00065 ---- Global ---- 00066 reset : in std_logic; -- 0 - сброс 00067 clk : in std_logic; -- тактовая частота 00068 00069 ---- Запись адреса ---- 00070 data_in : in std_logic_vector( 31 downto 0 ); -- шина данных памяти 00071 pci_adr_we : in std_logic; -- 1 - запись адреса 00072 pci_adr_h_we : in std_logic; -- 1 - запись старших разрядов адреса 00073 00074 ---- ctrl_main ---- 00075 dma_chn : in std_logic; -- номер канала DMA 00076 dsc_correct : out std_logic; -- 1 - загружен правильный дескриптор 00077 dsc_cmd : out std_logic_vector( 7 downto 0 ); -- командное слово дескриптора 00078 dsc_change_adr : in std_logic; -- 1 - смена адреса дескриптора 00079 dsc_change_mode : in std_logic; -- Режим изменения адреса: 00080 -- 0: - увеличение 00081 -- 1: - переход к нулевомй дескриптору 00082 dsc_load_en : in std_logic; -- 1 - разрешение записи дескриптора 00083 00084 ---- ctrl_dma_ext_cmd --- 00085 ram0_wr : in std_logic; -- 1 - запись в память дескрипторов 00086 dma_wraddr : in std_logic_vector( 11 downto 0 ); -- адрес памяти 00087 dma_wrdata : in std_logic_vector( 63 downto 0 ); -- данные DMA 00088 dsc_adr_h : out std_logic_vector( 7 downto 0 ); -- адрес, байт 4 00089 dsc_adr : out std_logic_vector( 23 downto 0 ); -- адрес, байты 3..1 00090 dsc_size : out std_logic_vector( 23 downto 0 ); -- размер, байты 3..1 00091 00092 ---- Контрольные точки ---- 00093 test : out std_logic_vector( 3 downto 0 ) 00094 00095 00096 ); 00097 end component; 00098 00099 end package; 00100 00101 library ieee; 00102 use ieee.std_logic_1164.all; 00103 use ieee.std_logic_arith.all; 00104 use ieee.std_logic_unsigned.all; 00105 00106 library unisim; 00107 use unisim.vcomponents.all; 00108 00109 00110 entity ctrl_ext_descriptor is 00111 generic( 00112 is_dsp48 : in integer:=1 -- 1 - использовать DSP48, 0 - не использовать DSP48 00113 ); 00114 port( 00115 ---- Global ---- 00116 reset : in std_logic; -- 0 - сброс 00117 clk : in std_logic; -- тактовая частота 00118 00119 ---- Запись адреса ---- 00120 data_in : in std_logic_vector( 31 downto 0 ); -- шина данных памяти 00121 pci_adr_we : in std_logic; -- 1 - запись адреса 00122 pci_adr_h_we : in std_logic; -- 1 - запись старших разрядов адреса 00123 00124 ---- ctrl_main ---- 00125 dma_chn : in std_logic; -- номер канала DMA 00126 dsc_correct : out std_logic; -- 1 - загружен правильный дескриптор 00127 dsc_cmd : out std_logic_vector( 7 downto 0 ); -- командное слово дескриптора 00128 dsc_change_adr : in std_logic; -- 1 - смена адреса дескриптора 00129 dsc_change_mode : in std_logic; -- Режим изменения адреса: 00130 -- 0: - увеличение 00131 -- 1: - переход к нулевомй дескриптору 00132 dsc_load_en : in std_logic; -- 1 - разрешение записи дескриптора 00133 00134 ---- ctrl_dma_ext_cmd --- 00135 ram0_wr : in std_logic; -- 1 - запись в память дескрипторов 00136 dma_wraddr : in std_logic_vector( 11 downto 0 ); -- адрес памяти 00137 dma_wrdata : in std_logic_vector( 63 downto 0 ); -- данные DMA 00138 dsc_adr_h : out std_logic_vector( 7 downto 0 ); -- адрес, байт 4 00139 dsc_adr : out std_logic_vector( 23 downto 0 ); -- адрес, байты 3..1 00140 dsc_size : out std_logic_vector( 23 downto 0 ); -- размер, байты 3..1 00141 00142 ---- Контрольные точки ---- 00143 test : out std_logic_vector( 3 downto 0 ) 00144 00145 00146 ); 00147 end ctrl_ext_descriptor; 00148 00149 00150 architecture ctrl_ext_descriptor of ctrl_ext_descriptor is 00151 00152 signal ram_a_out : std_logic_vector( 63 downto 0 ); 00153 signal ram_a_in : std_logic_vector( 63 downto 0 ); 00154 signal ram_a_adr : std_logic_vector( 8 downto 0 ); 00155 signal ram_a_wr : std_logic; 00156 signal ram_b_wr : std_logic; 00157 signal ram_b_adr : std_logic_vector( 8 downto 0 ); 00158 00159 --signal reg0 : std_logic_vector( 7 downto 0 ); 00160 --signal reg1 : std_logic_vector( 7 downto 0 ); 00161 --signal reg2 : std_logic_vector( 7 downto 0 ); 00162 00163 signal reg_write : std_logic; 00164 00165 signal status : std_logic_vector( 7 downto 0 ); 00166 00167 --signal reg84_wr : std_logic; 00168 --signal reg88_wr : std_logic; 00169 00170 signal port_a : std_logic_vector( 17 downto 0 ); 00171 signal port_b : std_logic_vector( 17 downto 0 ); 00172 signal port_c : std_logic_vector( 47 downto 0 ); 00173 signal port_p : std_logic_vector( 47 downto 0 ); 00174 signal opmode : std_logic_vector( 6 downto 0 ); 00175 signal carry : std_logic; 00176 00177 signal reg_0 : std_logic_vector( 7 downto 0 ); 00178 signal reg_1 : std_logic_vector( 7 downto 0 ); 00179 signal reg_2 : std_logic_vector( 7 downto 0 ); 00180 --signal reg_3 : std_logic_vector( 7 downto 0 ); 00181 --signal reg_4 : std_logic_vector( 7 downto 0 ); 00182 --signal reg_5 : std_logic_vector( 7 downto 0 ); 00183 --signal reg_6 : std_logic_vector( 7 downto 0 ); 00184 --signal reg_7 : std_logic_vector( 7 downto 0 ); 00185 00186 signal reg0_z : std_logic; 00187 signal crc_reset : std_logic; 00188 signal crc : std_logic_vector( 15 downto 0 ); 00189 signal crc_z : std_logic; 00190 signal sig_error : std_logic; 00191 signal dma_descriptor_error : std_logic; 00192 00193 begin 00194 00195 00196 --reg0 <= reg_di after 1 ns when rising_edge( clk ) and reg_write='1' and reg_adr( 2 downto 0 )="000"; -- адрес памяти 0 -- 00197 ----reg1 <= reg_di after 1 ns when rising_edge( clk ) and reg_write='1' and reg_adr( 2 downto 0 )="001"; -- адрес памяти 1 -- 00198 ----reg2 <= reg_di after 1 ns when rising_edge( clk ) and reg_write='1' and reg_adr( 2 downto 0 )="010"; -- регистр управления -- 00199 -- 00200 --reg_write <= reg_wr and reg_adr(7) and not reg_adr(6); -- декодирование адресов 0x80-0x8F 00201 -- 00202 --reg88_wr <= reg_write and reg_adr(3) after 1 ns; -- запись в регистр 88 00203 -- 00204 --pr_reg_write: process( clk ) begin 00205 -- if( rising_edge( clk ) ) then 00206 -- reg84_wr <= reg_write and reg_adr(2) after 1 ns; -- запись в регистр 84 00207 -- end if; 00208 --end process; 00209 -- 00210 -- 00211 --reg_0 <= reg_di after 1 ns when rising_edge( clk ) and reg88_wr='1'; 00212 --reg_1 <= reg_0 after 1 ns when rising_edge( clk ) and reg88_wr='1'; 00213 --reg_2 <= reg_1 after 1 ns when rising_edge( clk ) and reg88_wr='1'; 00214 --reg_3 <= reg_2 after 1 ns when rising_edge( clk ) and reg88_wr='1'; 00215 --reg_4 <= reg_3 after 1 ns when rising_edge( clk ) and reg88_wr='1'; 00216 --reg_5 <= reg_4 after 1 ns when rising_edge( clk ) and reg88_wr='1'; 00217 --reg_6 <= reg_5 after 1 ns when rising_edge( clk ) and reg88_wr='1'; 00218 --reg_7 <= reg_6 after 1 ns when rising_edge( clk ) and reg88_wr='1'; 00219 00220 --ram_a_in <= x"0000000000" & data_in( 31 downto 8 ); 00221 ram_a_in( 63 downto 32 ) <= (others=>'0'); 00222 ram_a_in( 31 downto 24 ) <= data_in( 7 downto 0 ) after 1 ns when rising_edge( clk ) and pci_adr_h_we='1'; 00223 ram_a_in( 23 downto 0 ) <= data_in( 31 downto 8 ); 00224 00225 ram_a_wr <= pci_adr_we; 00226 00227 ram_b_adr( 7 downto 0 ) <= dma_wraddr( 10 downto 3 ); 00228 ram_b_adr( 8 ) <= dma_chn; 00229 00230 ram_b_wr <= ram0_wr and dsc_load_en; 00231 00232 ram_a_adr( 7 downto 0 ) <= port_c( 7 downto 0 ); 00233 ram_a_adr( 8 ) <= dma_chn; 00234 00235 dsc_adr_h <= ram_a_out( 31 downto 24 ); 00236 dsc_adr <= ram_a_out( 23 downto 0 ); 00237 dsc_size <= ram_a_out( 63 downto 40 ); 00238 00239 dsc_cmd <= ram_a_out( 39 downto 32 ); 00240 00241 dsc_correct <= dma_descriptor_error; 00242 00243 00244 ram0: RAMB16_S36_S36 00245 generic map( 00246 SIM_COLLISION_CHECK => "NONE" 00247 ) 00248 00249 port map( 00250 DOA => ram_a_out( 31 downto 0 ), --: out std_logic_vector(3 downto 0); 00251 --DOB => ram_b_out( 31 downto 0 ), --: out std_logic_vector(31 downto 0); 00252 --DOPB : out std_logic_vector(3 downto 0); 00253 00254 ADDRA => ram_a_adr( 8 downto 0 ), --: in std_logic_vector(11 downto 0); 00255 ADDRB => ram_b_adr( 8 downto 0 ), --: in std_logic_vector(8 downto 0); 00256 CLKA => clk, 00257 CLKB => clk, 00258 DIA => ram_a_in( 31 downto 0 ), --: in std_logic_vector(3 downto 0); 00259 DIB => dma_wrdata( 31 downto 0 ), --: in std_logic_vector(31 downto 0); 00260 DIPA => (others=>'0'), 00261 DIPB => (others=>'0'), 00262 ENA => '1', 00263 ENB => '1' , 00264 SSRA => '0', 00265 SSRB => '0', 00266 WEA => ram_a_wr, 00267 WEB => ram_b_wr 00268 ); 00269 00270 ram1: RAMB16_S36_S36 00271 generic map( 00272 SIM_COLLISION_CHECK => "NONE" 00273 ) 00274 00275 port map( 00276 DOA => ram_a_out( 63 downto 32 ), --: out std_logic_vector(3 downto 0); 00277 --DOB => ram_b_out( 31 downto 0 ), --: out std_logic_vector(31 downto 0); 00278 --DOPB : out std_logic_vector(3 downto 0); 00279 00280 ADDRA => ram_a_adr( 8 downto 0 ), --: in std_logic_vector(11 downto 0); 00281 ADDRB => ram_b_adr( 8 downto 0 ), --: in std_logic_vector(8 downto 0); 00282 CLKA => clk, 00283 CLKB => clk, 00284 DIA => ram_a_in( 63 downto 32 ), --: in std_logic_vector(3 downto 0); 00285 DIB => dma_wrdata( 63 downto 32 ), --: in std_logic_vector(31 downto 0); 00286 DIPA => (others=>'0'), 00287 DIPB => (others=>'0'), 00288 ENA => '1', 00289 ENB => '1' , 00290 SSRA => '0', 00291 SSRB => '0', 00292 WEA => ram_a_wr, 00293 WEB => ram_b_wr 00294 ); 00295 00296 00297 00298 00299 00300 00301 --p1 <= reg2(1); 00302 --n1 <= not reg2(1); 00303 00304 -- reg0(2)=1 - изменение адреса: opmode=0x30 carry=1 00305 -- reg0(2)=0 - запись адреса из дескриптора: opmode=0x03 carry=0 00306 --opmode <= '0' & p1 & p1 & "00" & n1 & n1; 00307 --carry <= p1; 00308 opmode <= "0110000"; 00309 carry <= '1'; 00310 00311 port_b <= x"0000" & "00"; 00312 port_a <= x"0000" & "00"; 00313 00314 00315 gen_dsp48: if( is_dsp48=1 ) generate 00316 00317 dsp: DSP48 00318 generic map( 00319 00320 AREG => 1, 00321 B_INPUT => "DIRECT", 00322 BREG => 1, 00323 CARRYINREG => 1, 00324 CARRYINSELREG => 1, 00325 CREG => 1, 00326 LEGACY_MODE => "MULT18X18S", 00327 MREG => 1, 00328 OPMODEREG => 1, 00329 PREG => 1, 00330 SUBTRACTREG => 1 00331 ) 00332 00333 port map( 00334 --BCOUT : out std_logic_vector(17 downto 0); 00335 P => port_p, 00336 --PCOUT : out std_logic_vector(47 downto 0); 00337 00338 A => port_a, 00339 B => port_b, 00340 BCIN => (others=>'0'), 00341 C => port_c, 00342 CARRYIN => carry, 00343 CARRYINSEL => "00", 00344 CEA => '1', 00345 CEB => '1', 00346 CEC => '1', 00347 CECARRYIN => '1', 00348 CECINSUB => '1', 00349 CECTRL => '1', 00350 CEM => '1', 00351 CEP => '1', 00352 CLK => clk, 00353 OPMODE => opmode, 00354 PCIN => (others=>'0'), 00355 RSTA => '0', 00356 RSTB => '0', 00357 RSTC => '0', 00358 RSTCARRYIN => '0', 00359 RSTCTRL => '0', 00360 RSTM => '0', 00361 RSTP => dsc_change_mode, 00362 SUBTRACT => '0' 00363 ); 00364 00365 00366 end generate; 00367 00368 gen_ndsp48: if( is_dsp48=0 ) generate 00369 00370 pr_dsp: process( clk ) begin 00371 if( rising_edge( clk ) ) then 00372 if( dsc_change_mode='1' ) then 00373 port_p( 11 downto 0 ) <= (others=>'0') after 1 ns; 00374 else 00375 port_p( 11 downto 0 ) <= port_c( 11 downto 0 ) + 1 after 1 ns; 00376 end if; 00377 end if; 00378 end process; 00379 00380 end generate; 00381 00382 gen_ram: for ii in 0 to 11 generate 00383 00384 ram_adr: ram16x1d 00385 port map( 00386 we => dsc_change_adr, 00387 d => port_p(ii), 00388 wclk => clk, 00389 a0 => dma_chn, 00390 a1 => '0', 00391 a2 => '0', 00392 a3 => '0', 00393 spo => port_c(ii), 00394 dpra0 => '0', 00395 dpra1 => '0', 00396 dpra2 => '0', 00397 dpra3 => '1' 00398 ); 00399 00400 end generate; 00401 00402 port_c( 47 downto 12 ) <= (others=>'0'); 00403 00404 reg0_z <= dsc_load_en after 1 ns when rising_edge( clk ); 00405 crc_reset <= '1' when dsc_load_en='1' and reg0_z='0' else '0'; 00406 00407 ---- Проверка дескриптора ---- 00408 pr_crc: process( clk ) 00409 00410 variable v : std_logic_vector( 15 downto 0 ); 00411 00412 begin 00413 if( rising_edge( clk ) ) then 00414 if( crc_reset='1' ) then 00415 crc <= (others=>'1') after 1 ns; 00416 elsif( ram_b_wr='1' ) then 00417 v := crc xor 00418 dma_wrdata( 15 downto 0 ) xor 00419 dma_wrdata( 31 downto 16 ) xor 00420 dma_wrdata( 47 downto 32 ) xor 00421 dma_wrdata( 63 downto 48 ); 00422 00423 crc( 15 downto 1 ) <= v( 14 downto 0 ) after 1 ns; 00424 crc( 0 ) <= not v( 15 ) after 1 ns; 00425 end if; 00426 end if; 00427 end process; 00428 00429 crc_z <= '1' when crc=x"0001" else '0'; 00430 dma_descriptor_error <= not ( (not crc_z) or sig_error ) after 1 ns when rising_edge( clk ); 00431 00432 pr_sig: process( clk ) begin 00433 if( rising_edge( clk ) ) then 00434 if( ram_b_wr='1' ) then 00435 if( dma_wrdata( 47 downto 32 )=x"4953" ) then 00436 sig_error <= '0' after 1 ns; 00437 else 00438 sig_error <= '1' after 1 ns; 00439 end if; 00440 end if; 00441 end if; 00442 end process; 00443 00444 00445 end ctrl_ext_descriptor;