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_ram_cmd.vhd] - Rev 53

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
--
-- Title       : ctrl_ram_cmd
-- Author      : Dmitry Smekhov
-- Company     : Instrumental Systems
-- E-mail      : dsmv@insys.ru
--
-- Version     : 1.5
--
-------------------------------------------------------------------------------
--
-- Description : 	Узел управления памятью
--
-------------------------------------------------------------------------------
--
--  Version 1.5  07.03.2016
--				 Исправлено формирование ram_adrb при is_dsp48=0
--
-------------------------------------------------------------------------------
--
--  Version 1.4  09.04.2012
--				 Исправлено формирование 
--                               ch0_next_block, ch1_next_block
--
-------------------------------------------------------------------------------
--
--  Version 1.3  06.12.2011
--				 Добавлен local_adr_we
--
-------------------------------------------------------------------------------
--
--  Version 1.2  05.04.2010
--				 Добавлен параметр is_dsp48 - разрешение использования
--				 блоков DSP48
--
-------------------------------------------------------------------------------
--
--  Version 1.1   02.09.2009
--					Исправлен сброс ch1_adr_hi
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;				  
 
package ctrl_ram_cmd_pkg is
 
component ctrl_ram_cmd is				  
	generic(
		is_dsp48			: in integer:=1		-- 1 - использовать DSP48, 0 - не использовать DSP48
	);
	port(
		---- Global ----
		reset				: in std_logic;	-- 0 - сброс
		clk					: in std_logic;		--! Тактовая частота ядра - 250 МГц
		aclk				: in std_logic;		--! Тактовая частота локальной шины - 266 МГц
 
		---- Picoblaze ----
		dma_chn				: in std_logic;							-- номер канала DMA	  
		reg_ch0_ctrl		: in std_logic_vector( 7 downto 0 );	-- регистр управления
		reg_ch1_ctrl		: in std_logic_vector( 7 downto 0 );	-- регистр управления
		reg_write_E0		: in std_logic;		-- 1 - смена блока памяти
		dma0_transfer_rdy	: out  std_logic;	-- 1 - блок памяти готов к обмену
		dma1_transfer_rdy	: out  std_logic;	-- 1 - блок памяти готов к обмену
		loc_adr_we			: in std_logic;	-- 1 - запись локального адреса
 
		---- PLB_BUS ----			  
		dmar0				: in  std_logic;	-- 1 - запрос DMA 0
		dmar1				: in  std_logic;	-- 1 - запрос DMA 1	  
		request_wr			: out std_logic;	--! 1 - запрос на запись в регистр 
		request_rd			: out std_logic;	--! 1 - запрос на чтение из регистра 
		allow_wr			: in  std_logic;	--! 1 - разрешение записи 
		pb_complete			: in  std_logic;	--! 1 - завершение обмена по шине PLD_BUS
 
 
		pf_repack_we		: in  std_logic;	-- 1 - запись в память
		pf_ram_rd_out		: out std_logic;	-- 1 - чтение из памяти
 
		---- Память ----	   
		ram_adra_a9			: out std_logic;	-- разряд 9 адреса памяти
		ram_adrb			: out std_logic_vector( 10 downto 0 )
 
	);
 
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;
 
 
use work.ctrl_ram_cmd_pb_pkg.all;
 
entity ctrl_ram_cmd is				  
	generic(
		is_dsp48			: in integer:=1		-- 1 - использовать DSP48, 0 - не использовать DSP48
	);
	port(
		---- Global ----
		reset				: in std_logic;	-- 0 - сброс
		clk					: in std_logic;		--! Тактовая частота ядра - 250 МГц
		aclk				: in std_logic;		--! Тактовая частота локальной шины - 266 МГц
 
		---- Picoblaze ----
		dma_chn				: in std_logic;							-- номер канала DMA	  
		reg_ch0_ctrl		: in std_logic_vector( 7 downto 0 );	-- регистр управления
		reg_ch1_ctrl		: in std_logic_vector( 7 downto 0 );	-- регистр управления
		reg_write_E0		: in std_logic;		-- 1 - смена блока памяти
		dma0_transfer_rdy	: out  std_logic;	-- 1 - блок памяти готов к обмену
		dma1_transfer_rdy	: out  std_logic;	-- 1 - блок памяти готов к обмену
		loc_adr_we			: in std_logic;	-- 1 - запись локального адреса
 
		---- PLB_BUS ----			  
		dmar0				: in  std_logic;	-- 1 - запрос DMA 0
		dmar1				: in  std_logic;	-- 1 - запрос DMA 1
		request_wr			: out std_logic;	--! 1 - запрос на запись в регистр 
		request_rd			: out std_logic;	--! 1 - запрос на чтение из регистра 
		allow_wr			: in  std_logic;	--! 1 - разрешение записи 
		pb_complete			: in  std_logic;	--! 1 - завершение обмена по шине PLD_BUS
 
		pf_repack_we		: in  std_logic;	-- 1 - запись в память
		pf_ram_rd_out		: out std_logic;	-- 1 - чтение из памяти
 
		---- Память ----	   
		ram_adra_a9			: out std_logic;	-- разряд 9 адреса памяти
		ram_adrb			: out std_logic_vector( 10 downto 0 )
 
	);
 
end ctrl_ram_cmd;
 
 
architecture ctrl_ram_cmd of ctrl_ram_cmd is				 
 
signal	pb_current_block: std_logic_vector( 1 downto 0 );
signal	flag_data		: std_logic_vector( 3 downto 0 );
 
signal	cb				: std_logic;
 
signal	pb_flag_set		: std_logic_vector( 3 downto 0 );
signal	pb_flag_clr		: std_logic_vector( 3 downto 0 );
 
signal	pf_flag_set		: std_logic_vector( 3 downto 0 );
signal	pf_flag_clr		: std_logic_vector( 3 downto 0 );
 
signal	pb_fclr			: std_logic;
signal	pb_fset			: std_logic;
 
signal	reg_write_E0_z	: std_logic;
signal	reg_write_E0_z1	: std_logic;
 
signal	pf_chn			: std_logic;
signal	pf0_act			: std_logic;
signal	pf0_rdy			: std_logic;
signal	pf1_act			: std_logic;
signal	pf1_rdy			: std_logic;
 
type stp_type is ( s0, s1, s2, s3 );
signal	stp		: stp_type;
 
signal	rst_p			: std_logic;		
signal	rst_p0			: std_logic;
 
signal	pf0_cb			: std_logic;
signal	pf0_dma_wr_rdy	: std_logic;
signal	pf0_dma_rd_rdy	: std_logic;
 
signal	pf1_cb			: std_logic;
signal	pf1_dma_wr_rdy	: std_logic;
signal	pf1_dma_rd_rdy	: std_logic;
 
signal	ram0_transfer_rdy	: std_logic;
signal	ram1_transfer_rdy	: std_logic;	
 
signal	port_a		: std_logic_vector( 17 downto 0 );
signal	port_b		: std_logic_vector( 17 downto 0 );
signal	port_c		: std_logic_vector( 47 downto 0 );
signal	port_p		: std_logic_vector( 47 downto 0 );
signal  opmode		: std_logic_vector( 6 downto 0 );
signal	carry		: std_logic;
signal	cnt_rstp	: std_logic;		 
 
signal	ch0_adr_hi		: std_logic_vector( 1 downto 0 );
signal	ch1_adr_hi		: std_logic_vector( 1 downto 0 );
signal	ch0_next_block	: std_logic;
signal	ch1_next_block	: std_logic;
signal	ch0_adr_hi_wr	: std_logic;
signal	ch1_adr_hi_wr	: std_logic;
 
signal	pf_ram_rd		: std_logic;		  
signal	pf_dma_wr_rdy	: std_logic;
signal	pf_dma_rd_rdy	: std_logic;
 
signal	pf_stop_rd		: std_logic;
 
signal	loc_adr_ch0_we	: std_logic;
signal	loc_adr_ch1_we	: std_logic;
 
 
begin
 
cb <= pb_current_block( conv_integer( dma_chn ) );	 
ram_adra_a9 <= cb;
 
reg_write_E0_z <= reg_write_E0 after 1 ns when rising_edge( clk );
reg_write_E0_z1 <= reg_write_E0_z after 1 ns when rising_edge( clk );
 
 
pb_flag_clr(0) <= reg_ch0_ctrl(4) or ( reg_write_E0_z and reg_ch0_ctrl(2) and not dma_chn and not pb_current_block(0) ) after 1 ns when rising_edge( clk );	
pb_flag_clr(1) <= reg_ch0_ctrl(4) or ( reg_write_E0_z and reg_ch0_ctrl(2) and not dma_chn and     pb_current_block(0) ) after 1 ns when rising_edge( clk );	
pb_flag_clr(2) <= reg_ch1_ctrl(4) or ( reg_write_E0_z and reg_ch1_ctrl(2) and     dma_chn and not pb_current_block(1) ) after 1 ns when rising_edge( clk );	
pb_flag_clr(3) <= reg_ch1_ctrl(4) or ( reg_write_E0_z and reg_ch1_ctrl(2) and     dma_chn and     pb_current_block(1) ) after 1 ns when rising_edge( clk );	
 
pb_flag_set(0) <= reg_write_E0_z and not reg_ch0_ctrl(2) and not dma_chn and not pb_current_block(0) after 1 ns when rising_edge( clk );	
pb_flag_set(1) <= reg_write_E0_z and not reg_ch0_ctrl(2) and not dma_chn and     pb_current_block(0) after 1 ns when rising_edge( clk );	
pb_flag_set(2) <= reg_write_E0_z and not reg_ch1_ctrl(2) and     dma_chn and not pb_current_block(1) after 1 ns when rising_edge( clk );	
pb_flag_set(3) <= reg_write_E0_z and not reg_ch1_ctrl(2) and     dma_chn and     pb_current_block(1) after 1 ns when rising_edge( clk );	
 
 
pr_current_block0: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( reg_ch0_ctrl(4)='1' ) then
			pb_current_block(0) <= '0' after  1 ns;
		elsif( reg_write_E0_z1='1' and dma_chn='0' ) then
			pb_current_block(0) <= not pb_current_block(0) after 1 ns;
		end if;
	end if;
end process;
 
pr_current_block1: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( reg_ch1_ctrl(4)='1' ) then
			pb_current_block(1) <= '0' after  1 ns;
		elsif( reg_write_E0_z1='1' and dma_chn='1' ) then
			pb_current_block(1) <= not pb_current_block(1) after 1 ns;
		end if;
	end if;
end process;
 
 
 
gen_flag: for ii in 0 to 3 generate
 
process( clk ) begin
	if( rising_edge( clk ) ) then
		if( pb_flag_clr(ii)='1' or pf_flag_clr(ii)='1' or rst_p='1' ) then
			flag_data(ii) <= '0' after  1 ns;
		elsif( pb_flag_set(ii)='1' or pf_flag_set(ii)='1' ) then
			flag_data(ii) <= '1' after 1 ns;
		end if;
	end if;
end process;
 
 
end generate;			
 
 
---- Формирование готовности блока к обмену ----
pr0_transfer_rdy: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( reg_ch0_ctrl(2)='1' and flag_data( conv_integer(pb_current_block(0)) )='1' ) then
			ram0_transfer_rdy <= reg_ch0_ctrl(0) and not reg_ch0_ctrl(3) after 1 ns;
		elsif( reg_ch0_ctrl(2)='0' and flag_data( conv_integer(pb_current_block(0)) )='0' ) then
			ram0_transfer_rdy <= reg_ch0_ctrl(0) and not reg_ch0_ctrl(3)  after 1 ns;
		else
			ram0_transfer_rdy <= '0' after 1 ns;
		end if;
	end if;
end process;
 
pr1_transfer_rdy: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( reg_ch1_ctrl(2)='1' and flag_data( 2+conv_integer(pb_current_block(1)) )='1' ) then
			ram1_transfer_rdy <= reg_ch1_ctrl(0)  and not reg_ch1_ctrl(3) after 1 ns;
		elsif( reg_ch1_ctrl(2)='0' and flag_data( 2+conv_integer(pb_current_block(1)) )='0' ) then
			ram1_transfer_rdy <= reg_ch1_ctrl(0)  and not reg_ch1_ctrl(3) after 1 ns;
		else
			ram1_transfer_rdy <= '0' after 1 ns;
		end if;
	end if;
end process;			 
 
dma0_transfer_rdy <= ram0_transfer_rdy;
dma1_transfer_rdy <= ram1_transfer_rdy;
 
 
--ram_transfer_rdy <= (ram0_transfer_rdy and not dma_chn) or (ram1_transfer_rdy and dma_chn) after 1 ns
--				     when rising_edge( clk );
 
---- Перебор каналов DMA ----
 
rst_p0 <= not reset after 1 ns when rising_edge( aclk );
rst_p  <= rst_p0  after 1 ns when rising_edge( aclk );
 
pr_state: process( aclk ) begin
	if( rising_edge( aclk ) ) then
 
		case( stp ) is
			when s0 =>		  			
				cnt_rstp <= '0' after 1 ns;
				pf_chn <= '0' after 1 ns;
				pf0_act <= '1' after  1 ns;
				pf1_act <= '0' after  1 ns;
				if( pf0_rdy='1' ) then
					stp <= s1 after 1 ns;  
				end if;
 
			when s1 =>
				cnt_rstp <= '1' after 1 ns;
				pf0_act <= '0' after  1 ns;
				if( pf0_rdy='0' ) then
					stp <= s2 after 1 ns;
				end if;
 
			when s2 =>		  
				cnt_rstp <= '0' after 1 ns;
				pf_chn <= '1' after 1 ns;
				pf1_act <= '1' after  1 ns;
				if( pf1_rdy='1' ) then
					stp <= s3 after 1 ns;
				end if;
 
			when s3 =>		  
				cnt_rstp <= '1' after 1 ns;
				pf1_act <= '0' after  1 ns;
				if( pf1_rdy='0' ) then
					stp <= s0 after 1 ns;
				end if;
 
		end case;
 
		if( rst_p='1' ) then
			stp <= s0 after 1 ns; 
			pf0_act <= '0' after 1 ns;			
			cnt_rstp <= '1' after 1 ns;		
 
		end if;
 
	end if;
end process;				
 
 
 
cmd0: ctrl_ram_cmd_pb 
	port map(
		---- Global ----
		reset			=> reset,			-- 0 - сброс
		clk				=> clk,				-- тактовая частота 250 МГц 
		aclk			=> aclk,			-- тактовая частота 266 МГц 
 
		act				=> pf0_act,			-- 1 - разрешение цикла обработки
		rdy				=> pf0_rdy,			-- 1 - завершение цикла обработки
 
		loc_adr_we		=> loc_adr_ch0_we,			-- 1 - запись локального адреса
		flag_data		=> flag_data( 1 downto 0 ),		-- 1 - наличие данных в блоке
 
		flag_set		=> pf_flag_set( 1 downto 0 ),	-- 1 - установка флага наличия данных
		flag_clr		=> pf_flag_clr( 1 downto 0 ),	-- 1 - сброс флага наличия данных
		next_block		=> ch0_next_block,	-- 1 - признак достижения блока 4 килобайта
		adr_hi_wr		=> ch0_adr_hi_wr,	-- 1 - увеличение старших разрядов адреса для блока
 
		reg_ctrl		=> reg_ch0_ctrl( 7 downto 0 ),	 -- регистр управления
 
		dmar			=> dmar0,	-- 1 - запрос DMA					  
 
		pf_cb			=> pf0_cb,			-- номер текущего блока для обмена с шиной
		pf_dma_wr_rdy	=> pf0_dma_wr_rdy,	-- 1 - готовность передать 128 слов
		pf_dma_rd_rdy	=> pf0_dma_rd_rdy,	-- 1 - готовность принять 128 слов
 
		pf_ram_rd		=> pf_ram_rd,		-- 1 - чтение данных из памяти
		pf_repack_we	=> pf_repack_we		-- 1 - запись в память
	);
 
cmd1: ctrl_ram_cmd_pb 
	port map(
		---- Global ----
		reset			=> reset,			-- 0 - сброс
		clk				=> clk,				-- тактовая частота 250 МГц 
		aclk			=> aclk,			-- тактовая частота 266 МГц 
 
		act				=> pf1_act,			-- 1 - разрешение цикла обработки
		rdy				=> pf1_rdy,			-- 1 - завершение цикла обработки
 
		loc_adr_we		=> loc_adr_ch1_we,			-- 1 - запись локального адреса
		flag_data		=> flag_data( 3 downto 2 ),		-- 1 - наличие данных в блоке
 
		flag_set		=> pf_flag_set( 3 downto 2 ),	-- 1 - установка флага наличия данных
		flag_clr		=> pf_flag_clr( 3 downto 2 ),	-- 1 - сброс флага наличия данных
		next_block		=> ch1_next_block,	-- 1 - признак достижения блока 4 килобайта
		adr_hi_wr		=> ch1_adr_hi_wr,	-- 1 - увеличение старших разрядов адреса для блока
 
		reg_ctrl		=> reg_ch1_ctrl( 7 downto 0 ),	 -- регистр управления
 
		dmar			=> dmar1,	-- 1 - запрос DMA					  
 
		pf_cb			=> pf1_cb,			-- номер текущего блока для обмена с шиной
		pf_dma_wr_rdy	=> pf1_dma_wr_rdy,	-- 1 - готовность передать 128 слов
		pf_dma_rd_rdy	=> pf1_dma_rd_rdy,	-- 1 - готовность принять 128 слов
 
		pf_ram_rd		=> pf_ram_rd,		-- 1 - чтение данных из памяти
		pf_repack_we	=> pf_repack_we		-- 1 - запись в память
	);
 
pf_dma_wr_rdy <= pf0_dma_wr_rdy or pf1_dma_wr_rdy;
pf_dma_rd_rdy <= pf0_dma_rd_rdy or pf1_dma_rd_rdy;
 
request_wr <= pf_dma_wr_rdy;
request_rd <= pf_dma_rd_rdy;
 
ram_adrb(10) <= pf_chn;
ram_adrb(9) <= pf0_cb when pf_chn='0' else pf1_cb;		
 
--ram_adrb( 8 downto 7 ) <= ch0_adr_hi when pf_chn='0' else ch1_adr_hi;	
--	
--ram_adrb( 6 downto 0 ) <= port_p( 6 downto 0 ) after 1 ns;
 
ram_adrb( 8 downto 0 ) <= port_p( 8 downto 0 ) after 1 ns;
 
opmode <= "0100000";
carry <= pf_repack_we or pf_ram_rd;
 
pr_pf_ram_rd: process( aclk ) begin
	if( rising_edge( aclk ) ) then
		if( cnt_rstp='1' or port_p( 8 downto 0 )="111111111" ) or pf_stop_rd='1' or allow_wr='0' then
			pf_ram_rd <= '0' after 1 ns;
		elsif( 	pf_dma_wr_rdy='1' and allow_wr='1' ) then
			pf_ram_rd <= '1' after 1 ns;
		end if;
	end if;
end process;		
 
pr_stop_rd: process( aclk ) begin
	if( rising_edge( aclk ) ) then
		if( cnt_rstp='1' ) then
			pf_stop_rd <= '0' after 1 ns;
		elsif( port_p( 8 downto 0 )="111111111" ) then
			pf_stop_rd <= '1' after 1 ns;
		end if;
	end if;
end process;
 
--pf_ram_rd_out <= pf_ram_rd;
pf_ram_rd_out <= pf_ram_rd and allow_wr;
 
 
port_b <= x"0000" & "00";
port_a <= x"0000" & "00";		  
 
port_c <= port_p;
 
 
gen_dsp48: if( is_dsp48=1 ) generate
 
dsp: DSP48 
  generic map(
 
        AREG            => 1,
        B_INPUT         => "DIRECT",
        BREG            => 1,
        CARRYINREG      => 0,
        CARRYINSELREG   => 1,
        CREG            => 1,
        LEGACY_MODE     => "NONE",
        MREG            => 1,
        OPMODEREG       => 1,
        PREG            => 1,
        SUBTRACTREG     => 0
        )
 
  port map(
        --BCOUT                   : out std_logic_vector(17 downto 0);
        P                       => port_p,
        --PCOUT                   : out std_logic_vector(47 downto 0);
 
        A                       => port_a,
        B                       => port_b,
        BCIN                    => (others=>'0'),
        C                       => port_c,
        CARRYIN                 => carry,
        CARRYINSEL              => "00",
        CEA                     => '1',
        CEB                     => '1',
        CEC                     => '1',
        CECARRYIN               => '1',
        CECINSUB                => '1',
        CECTRL                  => '1',
        CEM                     => '1',
        CEP                     => '1',
        CLK                     => aclk,
        OPMODE                  => opmode,
        PCIN                    => (others=>'0'),
        RSTA                    => '0',
        RSTB                    => '0',
        RSTC                    => '0',
        RSTCARRYIN              => '0',
        RSTCTRL                 => '0',
        RSTM                    => '0',
        RSTP                    => cnt_rstp,
        SUBTRACT                => '0'
      );
 
end generate;
 
gen_ndsp48: if( is_dsp48=0 ) generate
 
port_p( 47 downto 9 ) <= (others=>'0');
 
pr_dsp: process( aclk ) begin
	if( rising_edge( aclk ) ) then
		if( cnt_rstp='1' ) then
			port_p( 8 downto 0 ) <= (others=>'0' ) after  1 ns;
		elsif( carry='1' ) then
			port_p( 8 downto 0 ) <= port_p( 8 downto 0 ) + 1 after  1 ns;
		end if;
	end if;
end process;
 
end generate;	
 
 
pr_ch0_adr_hi: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( reset='0' or reg_ch0_ctrl(4)='1' ) then
			ch0_adr_hi <= "00" after 1 ns;
		elsif( ch0_adr_hi_wr='1' ) then
			ch0_adr_hi <= ch0_adr_hi + 1 after  1 ns;
		end if;
	end if;
end process;
 
pr_ch1_adr_hi: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( reset='0' or reg_ch1_ctrl(4)='1' ) then
			ch1_adr_hi <= "00" after 1 ns;
		elsif( ch1_adr_hi_wr='1' ) then
			ch1_adr_hi <= ch1_adr_hi + 1 after  1 ns;
		end if;
	end if;
end process;
 
--ch0_next_block <= ch0_adr_hi(0) and  ch0_adr_hi(1);
--ch1_next_block <= ch1_adr_hi(0) and  ch1_adr_hi(1);
 
--ch0_next_block <= '1';
--ch1_next_block <= '1';
 
ch0_next_block <= pb_complete and pf0_act;
ch1_next_block <= pb_complete and pf1_act;
 
loc_adr_ch0_we <= loc_adr_we and not dma_chn;
loc_adr_ch1_we <= loc_adr_we and dma_chn;
 
 
end ctrl_ram_cmd;
 

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.