DS_DMA
|
00001 ------------------------------------------------------------------------------- 00002 -- 00003 -- Title : ctrl_dma_adr 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 21.01.2011 00017 -- Адрес расширен до 40 разрядов 00018 -- 00019 ------------------------------------------------------------------------------- 00020 -- 00021 -- Version 1.1 05.04.2010 00022 -- Добавлен параметр is_dsp48 - разрешение использования 00023 -- блоков DSP48 00024 -- 00025 ------------------------------------------------------------------------------- 00026 00027 library ieee; 00028 use ieee.std_logic_1164.all; 00029 00030 library unisim; 00031 use unisim.vcomponents.all; 00032 00033 00034 package ctrl_dma_adr_pkg is 00035 00036 component ctrl_dma_adr is 00037 generic( 00038 is_dsp48 : in integer:=1 -- 1 - использовать DSP48, 0 - не использовать DSP48 00039 ); 00040 port( 00041 ---- Global ---- 00042 clk : in std_logic; -- тактовая частота 00043 00044 ---- Доступ к PICOBLAZE ---- 00045 dma_chn : in std_logic; -- номер канала DMA 00046 reg0 : in std_logic_vector( 2 downto 0 ); -- регистр DMA_CTRL 00047 reg41_wr : in std_logic; -- 1 - запись в регистр 41 00048 00049 ---- CTRL_EXT_DESCRIPTOR ---- 00050 dsc_adr : in std_logic_vector( 23 downto 0 ); -- адрес, байты 3..1 00051 dsc_adr_h : in std_logic_vector( 7 downto 0 ); -- адрес, байт 4 00052 dsc_size : in std_logic_vector( 23 downto 0 ); -- размер, байты 3..1 00053 -- разряд 0 определяет направление работы, 0-чтение, 1-запись 00054 00055 ---- Адрес ---- 00056 pci_adr : out std_logic_vector( 39 downto 0 ); -- текущий адрес 00057 pci_size_z : out std_logic; -- 1 - размер равен 0 00058 pci_rw : out std_logic -- 0 - чтение, 1 - запись 00059 00060 ); 00061 end component; 00062 00063 end package; 00064 00065 00066 library ieee; 00067 use ieee.std_logic_1164.all; 00068 use ieee.std_logic_arith.all; 00069 use ieee.std_logic_unsigned.all; 00070 00071 library unisim; 00072 use unisim.vcomponents.all; 00073 00074 00075 entity ctrl_dma_adr is 00076 generic( 00077 is_dsp48 : in integer:=1 -- 1 - использовать DSP48, 0 - не использовать DSP48 00078 ); 00079 port( 00080 ---- Global ---- 00081 clk : in std_logic; -- тактовая частота 00082 00083 ---- Доступ к PICOBLAZE ---- 00084 dma_chn : in std_logic; -- номер канала DMA 00085 reg0 : in std_logic_vector( 2 downto 0 ); -- регистр DMA_CTRL 00086 reg41_wr : in std_logic; -- 1 - запись в регистр 41 00087 00088 ---- CTRL_EXT_DESCRIPTOR ---- 00089 dsc_adr : in std_logic_vector( 23 downto 0 ); -- адрес, байты 3..1 00090 dsc_adr_h : in std_logic_vector( 7 downto 0 ); -- адрес, байт 4 00091 dsc_size : in std_logic_vector( 23 downto 0 ); -- размер, байты 3..1 00092 00093 ---- Адрес ---- 00094 pci_adr : out std_logic_vector( 39 downto 0 ); -- текущий адрес 00095 pci_size_z : out std_logic; -- 1 - размер равен 0 00096 pci_rw : out std_logic -- 0 - чтение, 1 - запись 00097 00098 ); 00099 end ctrl_dma_adr; 00100 00101 00102 architecture ctrl_dma_adr of ctrl_dma_adr is 00103 00104 00105 signal port_a0 : std_logic_vector( 17 downto 0 ); 00106 signal port_b0 : std_logic_vector( 17 downto 0 ); 00107 signal port_c0 : std_logic_vector( 47 downto 0 ); 00108 signal port_p0 : std_logic_vector( 47 downto 0 ); 00109 signal opmode : std_logic_vector( 6 downto 0 ); 00110 signal carry0 : std_logic; 00111 00112 00113 signal port_a1 : std_logic_vector( 17 downto 0 ); 00114 signal port_b1 : std_logic_vector( 17 downto 0 ); 00115 signal port_c1 : std_logic_vector( 47 downto 0 ); 00116 signal port_p1 : std_logic_vector( 47 downto 0 ); 00117 signal carry1 : std_logic; 00118 signal subtract1 : std_logic; 00119 00120 signal p2 : std_logic; 00121 signal n2 : std_logic; 00122 00123 signal reg410_wr : std_logic; 00124 00125 signal adr_low : std_logic_vector( 2 downto 0 ); 00126 00127 begin 00128 00129 p2 <= reg0(2); 00130 n2 <= not reg0(2); 00131 00132 -- reg0(2)=1 - изменение адреса: opmode=0x30 carry=1 00133 -- reg0(2)=0 - запись адреса из дескриптора: opmode=0x03 carry=0 00134 opmode <= '0' & p2 & p2 & "00" & n2 & n2; 00135 carry0 <= p2; 00136 carry1 <= p2; 00137 subtract1 <= p2; 00138 00139 port_b0 <= dsc_adr( 21 downto 4 ); 00140 port_a0 <= x"00" & dsc_adr_h & dsc_adr( 23 downto 22 ); 00141 00142 --port_c0 <= port_p0; 00143 --port_c1 <= port_p1; 00144 00145 port_b1 <= dsc_size( 21 downto 4 ); 00146 port_a1 <= "00" & x"0000"; 00147 00148 pci_adr( 8 downto 0 ) <= (others=>'0'); 00149 pci_adr( 11 downto 9 ) <= adr_low( 2 downto 0 ); 00150 pci_adr( 31 downto 12 ) <= port_c0( 19 downto 0 ); 00151 pci_adr( 39 downto 32 ) <= port_c0( 27 downto 20 ); 00152 00153 gen_dsp48: if( is_dsp48=1 ) generate 00154 00155 dsp0: DSP48 00156 generic map( 00157 00158 AREG => 1, 00159 B_INPUT => "DIRECT", 00160 BREG => 1, 00161 CARRYINREG => 1, 00162 CARRYINSELREG => 1, 00163 CREG => 1, 00164 LEGACY_MODE => "MULT18X18S", 00165 MREG => 1, 00166 OPMODEREG => 1, 00167 PREG => 1, 00168 SUBTRACTREG => 1 00169 ) 00170 00171 port map( 00172 --BCOUT : out std_logic_vector(17 downto 0); 00173 P => port_p0, 00174 --PCOUT : out std_logic_vector(47 downto 0); 00175 00176 A => port_a0, 00177 B => port_b0, 00178 BCIN => (others=>'0'), 00179 C => port_c0, 00180 CARRYIN => carry0, 00181 CARRYINSEL => "00", 00182 CEA => '1', 00183 CEB => '1', 00184 CEC => '1', 00185 CECARRYIN => '1', 00186 CECINSUB => '1', 00187 CECTRL => '1', 00188 CEM => '1', 00189 CEP => '1', 00190 CLK => clk, 00191 OPMODE => opmode, 00192 PCIN => (others=>'0'), 00193 RSTA => '0', 00194 RSTB => '0', 00195 RSTC => '0', 00196 RSTCARRYIN => '0', 00197 RSTCTRL => '0', 00198 RSTM => '0', 00199 RSTP => '0', 00200 SUBTRACT => '0' 00201 ); 00202 00203 00204 00205 dsp1: DSP48 00206 generic map( 00207 00208 AREG => 1, 00209 B_INPUT => "DIRECT", 00210 BREG => 1, 00211 CARRYINREG => 1, 00212 CARRYINSELREG => 1, 00213 CREG => 1, 00214 LEGACY_MODE => "MULT18X18S", 00215 MREG => 1, 00216 OPMODEREG => 1, 00217 PREG => 1, 00218 SUBTRACTREG => 1 00219 ) 00220 00221 port map( 00222 --BCOUT : out std_logic_vector(17 downto 0); 00223 P => port_p1, 00224 --PCOUT : out std_logic_vector(47 downto 0); 00225 00226 A => port_a1, 00227 B => port_b1, 00228 BCIN => (others=>'0'), 00229 C => port_c1, 00230 CARRYIN => carry1, 00231 CARRYINSEL => "00", 00232 CEA => '1', 00233 CEB => '1', 00234 CEC => '1', 00235 CECARRYIN => '1', 00236 CECINSUB => '1', 00237 CECTRL => '1', 00238 CEM => '1', 00239 CEP => '1', 00240 CLK => clk, 00241 OPMODE => opmode, 00242 PCIN => (others=>'0'), 00243 RSTA => '0', 00244 RSTB => '0', 00245 RSTC => '0', 00246 RSTCARRYIN => '0', 00247 RSTCTRL => '0', 00248 RSTM => '0', 00249 RSTP => '0', 00250 SUBTRACT => subtract1 00251 ); 00252 00253 00254 pci_size_z <= port_p1( 47 ); 00255 00256 end generate; 00257 00258 gen_no_dsp48: if( is_dsp48=0 ) generate 00259 00260 pr_adr: process( clk ) begin 00261 if( rising_edge( clk ) ) then 00262 if( p2='1' ) then 00263 port_p0( 19 downto 0 ) <= port_c0( 19 downto 0 ) + 1 after 1 ns; 00264 else 00265 port_p0( 19 downto 0 ) <= dsc_adr( 23 downto 4 ) after 1 ns; 00266 end if; 00267 end if; 00268 end process; 00269 00270 00271 pr_size: process( clk ) begin 00272 if( rising_edge( clk ) ) then 00273 if( p2='1' ) then 00274 port_p1( 18 downto 0 ) <= port_c1( 18 downto 0 ) - 1 after 1 ns; 00275 else 00276 port_p1( 18 downto 0 ) <= '0' & dsc_size( 21 downto 4 ) after 1 ns; 00277 end if; 00278 end if; 00279 end process; 00280 00281 pci_size_z <= port_p1( 18 ); 00282 00283 end generate; 00284 00285 gen_ram: for ii in 0 to 27 generate 00286 00287 ram0: ram16x1d 00288 port map( 00289 we => reg41_wr, 00290 d => port_p0(ii), 00291 wclk => clk, 00292 a0 => dma_chn, 00293 a1 => '0', 00294 a2 => '0', 00295 a3 => '0', 00296 spo => port_c0(ii), 00297 dpra0 => '0', 00298 dpra1 => '0', 00299 dpra2 => '0', 00300 dpra3 => '1' 00301 ); 00302 00303 ram1: ram16x1d 00304 port map( 00305 we => reg41_wr, 00306 d => port_p1(ii), 00307 wclk => clk, 00308 a0 => dma_chn, 00309 a1 => '0', 00310 a2 => '0', 00311 a3 => '0', 00312 spo => port_c1(ii), 00313 dpra0 => '0', 00314 dpra1 => '0', 00315 dpra2 => '0', 00316 dpra3 => '1' 00317 ); 00318 00319 end generate; 00320 00321 port_c0( 47 downto 28 ) <= (others=>'0'); 00322 port_c1( 47 downto 28 ) <= (others=>'0'); 00323 00324 00325 00326 00327 reg410_wr <= reg41_wr and n2; 00328 00329 ram2: ram16x1d 00330 port map( 00331 we => reg410_wr, 00332 d => dsc_size (0), 00333 wclk => clk , 00334 a0 => dma_chn, 00335 a1 => '0', 00336 a2 => '0', 00337 a3 => '0', 00338 spo => pci_rw, 00339 dpra0 => '0', 00340 dpra1 => '0', 00341 dpra2 => '0', 00342 dpra3 => '1' 00343 ); 00344 00345 00346 00347 gen_ram_low: for ii in 0 to 2 generate 00348 00349 ram_low: ram16x1d 00350 port map( 00351 we => reg41_wr, 00352 d => dsc_adr(ii+1), 00353 wclk => clk, 00354 a0 => dma_chn, 00355 a1 => '0', 00356 a2 => '0', 00357 a3 => '0', 00358 spo => adr_low(ii), 00359 dpra0 => '0', 00360 dpra1 => '0', 00361 dpra2 => '0', 00362 dpra3 => '1' 00363 ); 00364 00365 00366 end generate; 00367 00368 end ctrl_dma_adr;