dma_ctrl.vhd

来自「国外开源的一个片上网络系统的源代码」· VHDL 代码 · 共 276 行

VHD
276
字号
------------------------------------------------------------------
--								--
--	DMA_ctrl.vhd - DMA Control				--
--	Paul Dunn - Nallatech Ltd Copyright 1999		--
--	Description - 						--
--	This process feeds the user with the required DMA 	--
--	controls. 						--
--	This DMA control, contains two FIFOs one for outputting	--
--	data and the other for inputing data.			--
--	The empty and half-full flags are used as indicators	--
--	to other parts of the design as to whether they have	--
--	data or can receive data.				--
--	There are two DMA counts.  One counts data coming in 	--
--	and out of the user application.			--
--	The other counts data coming in and out from the 	--
--	Spartan interface.					--
--	DMA enable and DMA direction are generated elsewhere.	--
--								--
------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity DMA_CTRL is
    port (	-- Interface clock.
        	CLK: in STD_LOGIC;
       	 	-- Global reset.
       	 	RST: in STD_LOGIC;
        	-- DMA enabled.
        	DMA_ENABLE: in STD_LOGIC;
        	-- DMA direction.
        	DMA_DIRECTION: in STD_LOGIC;
        	-- Read DMA data.
        	RD_DMA: in STD_LOGIC;
        	-- Write DMA data.
        	WR_DMA: in STD_LOGIC;
        	-- Write DMA count.
        	WR_COUNT: in STD_LOGIC;
       	 	-- DMA input data.
       	 	DMA_IN: in STD_LOGIC_VECTOR (31 downto 0);
        	-- DMA count input data.
        	COUNT_IN: in STD_LOGIC_VECTOR (31 downto 0);
        	-- DMA write enable.
        	DMA_WEN: in STD_LOGIC;
        	-- DMA read enable.
        	DMA_REN: in STD_LOGIC;	
        	-- DMA reset.
        	DMA_RST: in STD_LOGIC;
        	-- Terminal count of DMA counter.
        	TERM_CNT: out STD_LOGIC;	   
        	-- Local DMA buffer full.
        	DMA_IN_FULL: out STD_LOGIC;
        	-- Local DMA buffer empty.
        	DMA_IN_EMPTY: out STD_LOGIC;
        	-- Local DMA buffer full
        	DMA_OUT_FULL: out STD_LOGIC;
        	-- Local DMA buffer empty.
        	DMA_OUT_EMPTY: out STD_LOGIC;
        	-- DMA output data.
        	DMA_OUT: out STD_LOGIC_VECTOR (31 downto 0);
        	-- DMA count output data.
        	COUNT_OUT: out STD_LOGIC_VECTOR (31 downto 0);
        	-- DMA local buffer is ready for data.
        	DMA_RDY: out STD_LOGIC;
        	-- DMA local buffer has data ready to send.
        	DMA_DATA_AVAILABLE: out STD_LOGIC;
        	-- Current DMA count (from the perspective of the user application).
        	DMA_COUNT: out STD_LOGIC_VECTOR (31 downto 0);
        	-- DMA data.
        	DMA_DATA: inout STD_LOGIC_VECTOR (31 downto 0)
    		);
end DMA_CTRL;

architecture DMA_CTRL_arch of DMA_CTRL is

-- Synchronous FIFO using LUT RAMs.
component FWFRFF_32 generic (	NEEDBACKUPg : integer range 0 to 1 := 0;
				ATLEASTNEMPTYg : integer range 0 to 15 := 8;
				ATLEASTNFULLg : integer range 0 to 15 := 8
				);
			port (	DI : in std_logic_vector(31 downto 0);
				DO : out std_logic_vector(31 downto 0);
				WEN : in std_logic;
				CLK : in std_logic;
				REN : in std_logic;
				GSR_RST : in std_logic;
				SW_RST : in std_logic;
				BACKUP : in std_logic;
				FULL : out std_logic;
				EMPTY : out std_logic;
				N_EMPTY : out std_logic;
				N_FULL : out std_logic
				);
end component;

--component FIFO_32
--	port (	RCLK : in std_logic;
--		WCLK : in std_logic;
--		READ_EN : in std_logic;
--		WRITE_EN : in std_logic;
--		FIFO_RST : in std_logic;
--		D : in std_logic_vector (31 downto 0);
--		Q : out std_logic_vector (31 downto 0);
--		FIFO_STATUS : out std_logic_vector (4 downto 0);
--		FIFO_FULL : out std_logic;
--		FIFO_EMPTY : out std_logic
--		);
--end component;

-- FIFO in/out buses.
signal INFIFO_OUT : std_logic_vector (31 downto 0);
signal OUTFIFO_IN : std_logic_vector (31 downto 0);

-- DMA ready and data available signals.
signal DMA_DATA_AVAILABLEl : std_logic;
signal DMA_RDYl : std_logic;

-- DMA counts.
signal COUNT1, COUNT2 : std_logic_vector (31 downto 0);

signal DMA_RSTi: std_logic;

signal INFIFO_STATUS, OUTFIFO_STATUS: std_logic_vector(4 downto 0);
signal INFIFO_FULL, OUTFIFO_FULL: std_logic;

signal ZERO : std_logic;
signal ZEROS : std_logic_vector (31 downto 0);
signal ONE : std_logic_vector (31 downto 0);

signal FIFO_RST: std_logic;

begin

ZERO <= '0';
ZEROS <= (others => '0');
ONE <= (0 => '1', others => '0');		

-- Determine if DMA data bus is being driven.
DMA_DATA <= INFIFO_OUT when DMA_DIRECTION='0' else (others => 'Z'); 
OUTFIFO_IN <= DMA_DATA;

-- Input FIFO.  Data from the Spartan.
H1_INFIFO : FWFRFF_32 generic map (NEEDBACKUPg => 0,
				ATLEASTNEMPTYg => 8,
				ATLEASTNFULLg => 8
				)
		port map (	DI => DMA_IN,
				DO => INFIFO_OUT,
				WEN => WR_DMA,
				CLK => CLK,
				REN => DMA_REN,
				GSR_RST => RST,
				SW_RST => DMA_RST,
				BACKUP => ZERO,
				FULL => open,
				EMPTY => DMA_DATA_AVAILABLEl,
				N_EMPTY => open,
				N_FULL => DMA_IN_FULL
				);	

DMA_IN_EMPTY <= DMA_DATA_AVAILABLEl;				

--H1_INFIFO : FIFO_32
--	port map (	
--		RCLK => CLK,
--		WCLK => CLK,
--		READ_EN => DMA_REN,
--		WRITE_EN => WR_DMA,
--		FIFO_RST => FIFO_RST,
--		D => DMA_IN,
--		Q => INFIFO_OUT,
--		FIFO_STATUS => INFIFO_STATUS,
--		FIFO_FULL => INFIFO_FULL,
--		FIFO_EMPTY => DMA_DATA_AVAILABLEl
--		);

--process (RST, CLK)
--begin 
--	if RST='1' then
--		DMA_IN_FULL <= '0';
--	elsif CLK'event and CLK='1' then
--		DMA_IN_FULL <= '0';
--		if INFIFO_STATUS(2)='1' or INFIFO_STATUS(3)='1' or INFIFO_STATUS(4)='1' or INFIFO_FULL='1' then
--			DMA_IN_FULL <= '1';
--		end if;
--	end if;
--end process;

DMA_DATA_AVAILABLE <= not DMA_DATA_AVAILABLEl when DMA_DIRECTION='0' else '0';

-- Output FIFO.  Data to the Spartan.
H2_OUTFIFO : FWFRFF_32 generic map(NEEDBACKUPg => 0,
				ATLEASTNEMPTYg => 8,
				ATLEASTNFULLg => 8
				)
		port map (	DI => OUTFIFO_IN,
				DO => DMA_OUT,
				WEN => DMA_WEN,
				CLK => CLK,
				REN => RD_DMA,
				GSR_RST => RST,
				SW_RST => DMA_RST,
				BACKUP => ZERO,
				FULL => open,
				EMPTY => DMA_OUT_EMPTY,
				N_EMPTY => open,
				N_FULL => DMA_RDYl
				);	

DMA_OUT_FULL <= DMA_RDYl;

--H2_OUTFIFO : FIFO_32
--	port map (	
--		RCLK => CLK,
--		WCLK => CLK,
--		READ_EN => RD_DMA,
--		WRITE_EN => DMA_WEN,
--		FIFO_RST => FIFO_RST,
--		D => OUTFIFO_IN,
--		Q => DMA_OUT,
--		FIFO_STATUS => OUTFIFO_STATUS,
--		FIFO_FULL => OUTFIFO_FULL,
--		FIFO_EMPTY => DMA_OUT_EMPTY
--		);

--process (RST, CLK)
--begin 
--	if RST='1' then
--		DMA_RDYl <= '0';
--	elsif CLK'event and CLK='1' then
--		DMA_RDYl <= '0';
--		if OUTFIFO_STATUS(2)='1' or OUTFIFO_STATUS(3)='1' or OUTFIFO_STATUS(4)='1' or OUTFIFO_FULL='1' then
--			DMA_RDYl <= '1';
--		end if;
--	end if;
--end process;

DMA_RDY <= not DMA_RDYl when DMA_DIRECTION='1' else '0';

-- DMA counters.
-- One counter is for the user application and allows that application to know if it still has to read or write.
-- One counter generates the terminal count for the main interface control.  This is decremented when data is written/read from the interface control.
-- The counter value read back to the Spartan can either be one counter or the other depending on data direction.  
-- The Spartan is only concerned with data written into these local FIFOs.
process (RST, CLK)
begin
	if RST='1' then
		COUNT1 <= (others => '1');
		COUNT2 <= (others => '1');
	elsif CLK'event and CLK='1' then
		if WR_COUNT='1' then
			COUNT1 <= COUNT_IN;
			COUNT2 <= COUNT_IN;
		else
			if DMA_DIRECTION='0' and DMA_REN='1' then
				COUNT2 <= COUNT2-1;
			elsif DMA_DIRECTION='1' and DMA_WEN='1' then
				COUNT2 <= COUNT2-1;
			end if;
			if DMA_DIRECTION='0' and WR_DMA='1' then
				COUNT1 <= COUNT1-1;
			elsif DMA_DIRECTION='1' and RD_DMA='1' then
				COUNT1 <= COUNT1-1;
			end if;
		end if;
	end if;
end process;

-- Generate counter outputs and terminal count.
TERM_CNT <= '1' when (COUNT1=ONE and (WR_DMA='1' or RD_DMA='1')) or COUNT1=ZEROS else '0';	
COUNT_OUT <= COUNT2 when DMA_DIRECTION='0' else COUNT1;
DMA_COUNT <= COUNT2;									

end DMA_CTRL_arch;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?