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