📄 image_dma.vhd
字号:
-- ================================================================================
-- (c) 2005 Altera Corporation. All rights reserved.
-- Altera products are protected under numerous U.S. and foreign patents, maskwork
-- rights, copyrights and other intellectual property laws.
--
-- This reference design file, and your use thereof, is subject to and governed
-- by the terms and conditions of the applicable Altera Reference Design License
-- Agreement (either as signed by you, agreed by you upon download or as a
-- "click-through" agreement upon installation andor found at www.altera.com).
-- By using this reference design file, you indicate your acceptance of such terms
-- and conditions between you and Altera Corporation. In the event that you do
-- not agree with such terms and conditions, you may not use the reference design
-- file and please promptly destroy any copies you have made.
--
-- This reference design file is being provided on an "as-is" basis and as an
-- accommodation and therefore all warranties, representations or guarantees of
-- any kind (whether express, implied or statutory) including, without limitation,
-- warranties of merchantability, non-infringement, or fitness for a particular
-- purpose, are specifically disclaimed. By making this reference design file
-- available, Altera expressly does not recommend, suggest or require that this
-- reference design file be used in combination with any other product not
-- provided by Altera.
--================================================================================
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
ENTITY image_dma IS
PORT (
resetn : IN std_logic;
clk : IN std_logic;
-- image base address
image_address : IN std_logic_vector(31 downto 0);
mode : IN std_logic;
-- image timing signals
hsync : IN std_logic;
vblank : IN std_logic;
-- image size signal
num_pixels_per_line : IN std_logic_vector(9 downto 0);
-- Avalon signals
readdatavalid : IN std_logic;
waitrequest : IN std_logic;
-- SRAM signals
address_to_sram : OUT std_logic_vector(31 downto 0);
data_from_sram : IN std_logic_vector(31 downto 0);
read_to_sram : OUT std_logic;
-- line buffer signals
data_to_buffer : OUT std_logic_vector(31 downto 0);
address_to_buffer : OUT std_logic_vector(8 downto 0);
write_to_buffer : OUT std_logic
);
END image_dma;
ARCHITECTURE rtl OF image_dma IS
TYPE state_type IS (idle, transferring, wait_state);
SIGNAL state : state_type;
SIGNAL read_to_sram_internal : std_logic;
SIGNAL address_to_buffer_internal : std_logic_vector(8 downto 0);
SIGNAL address_to_sram_internal : std_logic_vector(31 downto 0);
SIGNAL incr_expected_address : std_logic;
SIGNAL expected_address : std_logic_vector(31 downto 0);
SIGNAL hsync_delay : std_logic;
SIGNAL start_transfer : std_logic;
SIGNAL edge_detect_shift_register : std_logic_vector(3 downto 0);
SIGNAL edge_detect : std_logic;
SIGNAL vblank_delay : std_logic;
SIGNAL vblank_edge : std_logic;
SIGNAL tff_hsync : std_logic;
BEGIN
address_to_buffer <= address_to_buffer_internal;
data_to_buffer <= data_from_sram;
address_to_sram <= address_to_sram_internal;
read_to_sram <= read_to_sram_internal;
write_to_buffer <= readdatavalid;
PROCESS(resetn,clk)
BEGIN
IF resetn = '0' THEN
start_transfer <= '0';
edge_detect_shift_register <= "0000";
edge_detect <= '0';
hsync_delay <= '0';
vblank_delay <= '0';
vblank_edge <= '0';
tff_hsync <= '0';
ELSIF rising_edge(clk) THEN
edge_detect <= NOT(hsync) AND hsync_delay;
hsync_delay <= hsync;
vblank_delay <= vblank;
vblank_edge <= vblank AND NOT(vblank_delay);
edge_detect_shift_register(0) <= edge_detect;
edge_detect_shift_register(3 downto 1) <= edge_detect_shift_register(2 downto 0);
IF edge_detect_shift_register(3) = '1' AND vblank = '1' THEN -- JF Aug 29
tff_hsync <= NOT(tff_hsync);
ELSIF vblank = '0' THEN
tff_hsync <= '0'; -- JF Sept 18
END IF;
IF mode = '0' THEN
start_transfer <= edge_detect_shift_register(3);
ELSE
start_transfer <= edge_detect_shift_register(3) AND tff_hsync;
END IF;
END IF;
END PROCESS;
PROCESS(resetn,clk)
BEGIN
IF resetn = '0' THEN
address_to_sram_internal <= (others => '0');
address_to_buffer_internal <= (others => '0');
read_to_sram_internal <= '0';
incr_expected_address <= '0';
state <= idle;
ELSIF rising_edge(clk) THEN
CASE state IS
WHEN idle =>
read_to_sram_internal <= '0';
address_to_buffer_internal <= (others => '0');
IF vblank = '0' THEN
address_to_sram_internal <= image_address;
ELSE
address_to_sram_internal <= expected_address;
END IF;
IF (vblank = '1' AND start_transfer = '1') OR vblank_edge = '1' THEN
read_to_sram_internal <= '1';
incr_expected_address <= '1';
state <= transferring;
ELSE
incr_expected_address <= '0';
state <= idle;
END IF;
WHEN transferring =>
read_to_sram_internal <= '1';
incr_expected_address <= '0';
-- if hsync drops to 0 we are behind the current line transaction.
-- In this case drop out of the transferring state and go to idle
-- as the VGA driver won't use the pixels we are xferring.
--IF hsync = '0' THEN
IF edge_detect = '1' THEN
state <= idle;
-- We've reached the end of a transfer if the address_to_buffer = num_pixel_per_line - 1 for 8-bit mode
-- 16-bit mode
--ELSIF address_to_buffer_internal = num_pixels_per_line(9 downto 1) - 1 THEN
ELSIF address_to_sram_internal = expected_address - 4 THEN
read_to_sram_internal <= '0';
state <= wait_state;
ELSE
state <= transferring;
END IF;
-- IF wait request is low then we have valid data on the data_from_sram bus
IF waitrequest = '0' THEN
--address_to_buffer_internal <= address_to_buffer_internal+ 1;
address_to_sram_internal <= address_to_sram_internal + 4;
END IF;
IF readdatavalid = '1' THEN
address_to_buffer_internal <= address_to_buffer_internal+ 1;
END IF;
WHEN wait_state =>
read_to_sram_internal <= '0';
incr_expected_address <= '0';
IF readdatavalid = '1' THEN
address_to_buffer_internal <= address_to_buffer_internal+ 1;
END IF;
--IF hsync = '0' THEN
-- There were times when a transfer would finish while the current hsync
-- was 0. This would cause us to transition to idle before all pixels
-- had been xferred. Instead lets wait until a falling edge
-- of hsync before we xfer states.
IF edge_detect = '1' THEN
state <= idle;
ELSE
state <= wait_state;
END IF;
WHEN others =>
null;
END CASE;
END IF;
END PROCESS;
PROCESS(resetn,clk)
BEGIN
IF resetn = '0' THEN
expected_address <= (others => '0');
ELSIF rising_edge(clk) THEN
IF vblank = '0' THEN
expected_address <= image_address;
ELSIF incr_expected_address = '1' THEN
expected_address <= expected_address + (num_pixels_per_line & '0');
END IF;
END IF;
END PROCESS;
END rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -