📄 dma_event_gen.vhd
字号:
------------------------------------------------------------------------------
-- *** Disclaimer: This example code is provided with no support. ***
------------------------------------------------------------------------------
-- File : dma_event_gen.vhd
-- Author : Shraddha
-- Created :
-- Last modified : June 05, 2003
-- Project : OSD FPGA
------------------------------------------------------------------------------
-- Description : This module generates OSD dma events to the DSP.
--
------------------------------------------------------------------------------
-- Modification history :
-- Jan 22, 2003 : Shraddha : created
-- April 25, 2003 : Shraddha: Added soft reset to the module
-- June 04, 2003 : Shraddha : Added pipeline registering after subtracting
-- FIFO_USED from FIFO_DEPTH by moving FIFO_AVAIL logic inside a sequential
-- process.
-- June 05, 2003 : Shraddha : Changed DMA mechanism to count number of events
-- per Field. This module will only request the number of events specified
-- per field.
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity DMA_EVENT_GEN is
port (
-- from Power Supply
RESETz : in std_logic; -- System Reset
SRESETz : in std_logic; -- Soft Reset
-- Clock
EMIF_CLK : in std_logic; -- 100 Mhz EMIF Clock
-- from EMIF IF
FIFO_WE : in std_logic; -- Write Enable for Y FIFO
-- from registers
FIFO_THLD : in std_logic_vector(11 downto 0); -- threshold
EVTS_PER_FIELD : in std_logic_vector(15 downto 0);
-- from Video IF
VSYNC : in std_logic;
-- From state machine
EVT_EN : in std_logic; -- DMA Events enabled
-- from FIFO
FIFO_USED : in std_logic_vector(7 downto 0); -- FIFO usage
-- to DSP
OSD_EVT : out std_logic -- Video Display Event
);
end DMA_EVENT_GEN;
architecture RTL of DMA_EVENT_GEN is
constant FIFO_DEPTH : std_logic_vector := "11111111"; -- FIFO depth in words
signal DMA_PEND : std_logic; -- DMA pending with DSP
signal FIFO_AVAIL : unsigned(7 downto 0); -- Unused part of FIFO
signal P_OSD_EVT : std_logic; -- OSD event
signal L_EVTS_PER_FIELD : std_logic_vector(15 downto 0); -- latched value
-- of EVTS_PER_FIELD
signal EVT_CNTR : std_logic_vector(15 downto 0); -- counts number of event
-- per field
signal L1_S_VSYNC, S_VSYNC, M_VSYNC : std_logic; -- synchronizing signals
signal DMA_WR_COUNT : std_logic_vector(11 downto 0); -- counts the number of words received in each DMA
begin -- RTL
-- purpose: Monitors the FIFO_USED signal from the FIFO. The output
-- of this process is a signal that tells how much of the FIFO is
-- still available.
FIFO_WATCH : process (EMIF_CLK, RESETz)
begin -- process FIFO_WATCH
if RESETz = '0' or SRESETz = '0' then
FIFO_AVAIL <= unsigned(FIFO_DEPTH);
elsif EMIF_CLK'event and EMIF_CLK = '1' then
FIFO_AVAIL <= unsigned(FIFO_DEPTH) - unsigned(FIFO_USED);
end if;
end process FIFO_WATCH;
OSD_EVT <= P_OSD_EVT;
-- purpose: This process generates the actual event. If fifo_thld is
-- less than the FIFO_AVAIL and there is no DMA pending, and events
-- are enabled and the number of events in the field are less than
-- that specified by the EVTS_PER_FIELD signal, then an event is
-- generated.
EVT_GEN: process (EMIF_CLK, RESETz)
begin -- process EVT_GEN
if RESETz = '0' or SRESETz = '0' then -- asynchronous reset (active low)
P_OSD_EVT <= '0';
elsif EMIF_CLK'event and EMIF_CLK = '1' then -- rising clock edge
if FIFO_WE = '1' or EVT_EN = '0' then
P_OSD_EVT <= '0';
elsif unsigned(FIFO_THLD) <= FIFO_AVAIL(7 downto 0) and
DMA_PEND = '0' and EVT_EN = '1' and EVT_CNTR < L_EVTS_PER_FIELD then
P_OSD_EVT <= '1';
end if;
end if;
end process EVT_GEN;
-- purpose: Monitors the progress of the requested DMA. As long as
-- the DMA is not over, the DMA_PEND flag is kept active. The process
-- counts all the DMA writes to the FIFO and inactivates the DMA_PEND
-- flag when the number of writes equal FIFO_THLD.
DMA_MON: process (EMIF_CLK, RESETz)
begin -- process DMA_MON
if RESETz = '0' or SRESETz = '0' then -- asynchronous reset (active low)
DMA_PEND <= '0';
elsif EMIF_CLK'event and EMIF_CLK = '1' then -- rising clock edge
if (DMA_WR_COUNT = FIFO_THLD) or EVT_EN = '0' then
DMA_PEND <= '0';
elsif P_OSD_EVT = '1' then
DMA_PEND <= '1';
end if;
if DMA_PEND = '0' then
DMA_WR_COUNT <= (others => '0');
elsif FIFO_WE = '1' then
DMA_WR_COUNT <= DMA_WR_COUNT + 1;
else
DMA_WR_COUNT <= DMA_WR_COUNT;
end if;
end if;
end process DMA_MON;
-- purpose: This process monitors the number of events generated
-- per field. It latches the EVTS_PER_FIELD value at the start
-- of a VSYNC pulse and resets the EVT_CNTR. Whenever an event
-- occurs the EVT_CNTR is incremented.
EVT_MONITOR : process (EMIF_CLK, RESETz)
begin
if RESETz = '0' or SRESETz = '0' then
EVT_CNTR <= (others => '0');
L_EVTS_PER_FIELD <= (others => '0');
L1_S_VSYNC <= '0';
elsif EMIF_CLK'event and EMIF_CLK = '1' then
if L1_S_VSYNC = '0' and S_VSYNC = '1' then
EVT_CNTR <= (others => '0');
L_EVTS_PER_FIELD <= EVTS_PER_FIELD;
elsif DMA_PEND = '0' and P_OSD_EVT = '1' then
EVT_CNTR <= EVT_CNTR + 1;
L_EVTS_PER_FIELD <= L_EVTS_PER_FIELD;
end if;
L1_S_VSYNC <= S_VSYNC;
end if;
end process EVT_MONITOR;
-- purpose: Synchronize VCLK domain signal VSYNC to EMIF_CLK domain
SYNC : process(EMIF_CLK, RESETz)
begin
if RESETz = '0' and SRESETz = '0' then
M_VSYNC <= '0';
S_VSYNC <= '0';
elsif EMIF_CLK'event and EMIF_CLK = '1' then
M_VSYNC <= VSYNC;
S_VSYNC <= M_VSYNC;
end if;
end process SYNC;
end RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -