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 + -
显示快捷键?