⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image_dma.vhd

📁 VGA控制器源码
💻 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 + -