OpenCores
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 2

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;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.