URL
https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk
Subversion Repositories pcie_ds_dma
[/] [pcie_ds_dma/] [trunk/] [core/] [ds_dma64/] [pcie_src/] [pcie_core64_m1/] [pcie_fifo_ext/] [ctrl_dma_adr.vhd] - Rev 32
Go to most recent revision | Compare with Previous | Blame | View Log
------------------------------------------------------------------------------- -- -- Title : ctrl_dma_adr -- Author : Dmitry Smekhov -- Company : Instrumental Systems -- E-mail : dsmv@insys.ru -- -- Version : 1.2 -- ------------------------------------------------------------------------------- -- -- Description : Узел формирования адреса и размера для текущей операции -- ------------------------------------------------------------------------------- -- -- Version 1.2 21.01.2011 -- Адрес расширен до 40 разрядов -- ------------------------------------------------------------------------------- -- -- Version 1.1 05.04.2010 -- Добавлен параметр is_dsp48 - разрешение использования -- блоков DSP48 -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; library unisim; use unisim.vcomponents.all; package ctrl_dma_adr_pkg is component ctrl_dma_adr is generic( is_dsp48 : in integer:=1 -- 1 - использовать DSP48, 0 - не использовать DSP48 ); port( ---- Global ---- clk : in std_logic; -- тактовая частота ---- Доступ к PICOBLAZE ---- dma_chn : in std_logic; -- номер канала DMA reg0 : in std_logic_vector( 2 downto 0 ); -- регистр DMA_CTRL reg41_wr : in std_logic; -- 1 - запись в регистр 41 ---- CTRL_EXT_DESCRIPTOR ---- dsc_adr : in std_logic_vector( 23 downto 0 ); -- адрес, байты 3..1 dsc_adr_h : in std_logic_vector( 7 downto 0 ); -- адрес, байт 4 dsc_size : in std_logic_vector( 23 downto 0 ); -- размер, байты 3..1 -- разряд 0 определяет направление работы, 0-чтение, 1-запись ---- Адрес ---- pci_adr : out std_logic_vector( 39 downto 0 ); -- текущий адрес pci_size_z : out std_logic; -- 1 - размер равен 0 pci_rw : out std_logic -- 0 - чтение, 1 - запись ); end component; end package; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library unisim; use unisim.vcomponents.all; entity ctrl_dma_adr is generic( is_dsp48 : in integer:=1 -- 1 - использовать DSP48, 0 - не использовать DSP48 ); port( ---- Global ---- clk : in std_logic; -- тактовая частота ---- Доступ к PICOBLAZE ---- dma_chn : in std_logic; -- номер канала DMA reg0 : in std_logic_vector( 2 downto 0 ); -- регистр DMA_CTRL reg41_wr : in std_logic; -- 1 - запись в регистр 41 ---- CTRL_EXT_DESCRIPTOR ---- dsc_adr : in std_logic_vector( 23 downto 0 ); -- адрес, байты 3..1 dsc_adr_h : in std_logic_vector( 7 downto 0 ); -- адрес, байт 4 dsc_size : in std_logic_vector( 23 downto 0 ); -- размер, байты 3..1 ---- Адрес ---- pci_adr : out std_logic_vector( 39 downto 0 ); -- текущий адрес pci_size_z : out std_logic; -- 1 - размер равен 0 pci_rw : out std_logic -- 0 - чтение, 1 - запись ); end ctrl_dma_adr; architecture ctrl_dma_adr of ctrl_dma_adr is signal port_a0 : std_logic_vector( 17 downto 0 ); signal port_b0 : std_logic_vector( 17 downto 0 ); signal port_c0 : std_logic_vector( 47 downto 0 ); signal port_p0 : std_logic_vector( 47 downto 0 ); signal opmode : std_logic_vector( 6 downto 0 ); signal carry0 : std_logic; signal port_a1 : std_logic_vector( 17 downto 0 ); signal port_b1 : std_logic_vector( 17 downto 0 ); signal port_c1 : std_logic_vector( 47 downto 0 ); signal port_p1 : std_logic_vector( 47 downto 0 ); signal carry1 : std_logic; signal subtract1 : std_logic; signal p2 : std_logic; signal n2 : std_logic; signal reg410_wr : std_logic; signal adr_low : std_logic_vector( 2 downto 0 ); begin p2 <= reg0(2); n2 <= not reg0(2); -- reg0(2)=1 - изменение адреса: opmode=0x30 carry=1 -- reg0(2)=0 - запись адреса из дескриптора: opmode=0x03 carry=0 opmode <= '0' & p2 & p2 & "00" & n2 & n2; carry0 <= p2; carry1 <= p2; subtract1 <= p2; port_b0 <= dsc_adr( 21 downto 4 ); port_a0 <= x"00" & dsc_adr_h & dsc_adr( 23 downto 22 ); --port_c0 <= port_p0; --port_c1 <= port_p1; port_b1 <= dsc_size( 21 downto 4 ); port_a1 <= "00" & x"0000"; pci_adr( 8 downto 0 ) <= (others=>'0'); pci_adr( 11 downto 9 ) <= adr_low( 2 downto 0 ); pci_adr( 31 downto 12 ) <= port_c0( 19 downto 0 ); pci_adr( 39 downto 32 ) <= port_c0( 27 downto 20 ); gen_dsp48: if( is_dsp48=1 ) generate dsp0: DSP48 generic map( AREG => 1, B_INPUT => "DIRECT", BREG => 1, CARRYINREG => 1, CARRYINSELREG => 1, CREG => 1, LEGACY_MODE => "MULT18X18S", MREG => 1, OPMODEREG => 1, PREG => 1, SUBTRACTREG => 1 ) port map( --BCOUT : out std_logic_vector(17 downto 0); P => port_p0, --PCOUT : out std_logic_vector(47 downto 0); A => port_a0, B => port_b0, BCIN => (others=>'0'), C => port_c0, CARRYIN => carry0, CARRYINSEL => "00", CEA => '1', CEB => '1', CEC => '1', CECARRYIN => '1', CECINSUB => '1', CECTRL => '1', CEM => '1', CEP => '1', CLK => clk, OPMODE => opmode, PCIN => (others=>'0'), RSTA => '0', RSTB => '0', RSTC => '0', RSTCARRYIN => '0', RSTCTRL => '0', RSTM => '0', RSTP => '0', SUBTRACT => '0' ); dsp1: DSP48 generic map( AREG => 1, B_INPUT => "DIRECT", BREG => 1, CARRYINREG => 1, CARRYINSELREG => 1, CREG => 1, LEGACY_MODE => "MULT18X18S", MREG => 1, OPMODEREG => 1, PREG => 1, SUBTRACTREG => 1 ) port map( --BCOUT : out std_logic_vector(17 downto 0); P => port_p1, --PCOUT : out std_logic_vector(47 downto 0); A => port_a1, B => port_b1, BCIN => (others=>'0'), C => port_c1, CARRYIN => carry1, CARRYINSEL => "00", CEA => '1', CEB => '1', CEC => '1', CECARRYIN => '1', CECINSUB => '1', CECTRL => '1', CEM => '1', CEP => '1', CLK => clk, OPMODE => opmode, PCIN => (others=>'0'), RSTA => '0', RSTB => '0', RSTC => '0', RSTCARRYIN => '0', RSTCTRL => '0', RSTM => '0', RSTP => '0', SUBTRACT => subtract1 ); pci_size_z <= port_p1( 47 ); end generate; gen_no_dsp48: if( is_dsp48=0 ) generate pr_adr: process( clk ) begin if( rising_edge( clk ) ) then if( p2='1' ) then port_p0( 19 downto 0 ) <= port_c0( 19 downto 0 ) + 1 after 1 ns; else port_p0( 19 downto 0 ) <= dsc_adr( 23 downto 4 ) after 1 ns; end if; end if; end process; pr_size: process( clk ) begin if( rising_edge( clk ) ) then if( p2='1' ) then port_p1( 18 downto 0 ) <= port_c1( 18 downto 0 ) - 1 after 1 ns; else port_p1( 18 downto 0 ) <= '0' & dsc_size( 21 downto 4 ) after 1 ns; end if; end if; end process; pci_size_z <= port_p1( 18 ); end generate; gen_ram: for ii in 0 to 27 generate ram0: ram16x1d port map( we => reg41_wr, d => port_p0(ii), wclk => clk, a0 => dma_chn, a1 => '0', a2 => '0', a3 => '0', spo => port_c0(ii), dpra0 => '0', dpra1 => '0', dpra2 => '0', dpra3 => '1' ); ram1: ram16x1d port map( we => reg41_wr, d => port_p1(ii), wclk => clk, a0 => dma_chn, a1 => '0', a2 => '0', a3 => '0', spo => port_c1(ii), dpra0 => '0', dpra1 => '0', dpra2 => '0', dpra3 => '1' ); end generate; port_c0( 47 downto 28 ) <= (others=>'0'); port_c1( 47 downto 28 ) <= (others=>'0'); reg410_wr <= reg41_wr and n2; ram2: ram16x1d port map( we => reg410_wr, d => dsc_size(0), wclk => clk, a0 => dma_chn, a1 => '0', a2 => '0', a3 => '0', spo => pci_rw, dpra0 => '0', dpra1 => '0', dpra2 => '0', dpra3 => '1' ); gen_ram_low: for ii in 0 to 2 generate ram_low: ram16x1d port map( we => reg41_wr, d => dsc_adr(ii+1), wclk => clk, a0 => dma_chn, a1 => '0', a2 => '0', a3 => '0', spo => adr_low(ii), dpra0 => '0', dpra1 => '0', dpra2 => '0', dpra3 => '1' ); end generate; end ctrl_dma_adr;
Go to most recent revision | Compare with Previous | Blame | View Log