DS_DMA
pcie_src/pcie_core64_m1/pcie_fifo_ext/ctrl_dma_adr.vhd
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;