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

📄 lancelot_vga.vhd

📁 基于FPGA的VGA控制器设计。对外支持普通VGA接口
💻 VHD
📖 第 1 页 / 共 3 页
字号:
---------------------------------
--         Lancelot            --
---------------------------------
--  Excalibur Video Controller --
---------------------------------
-- Written by Marco Groeneveld --
---------------------------------
-- History
---------------------------------
-- v5.0 : Avalon Master Lock
-- v4.1 : Proper Line Missed Status Added
-- v4.0 : Updated for Nios II
-- v3.2 : Removed internal reset_int state machine
-- v3.1 : Added DMA length and line length 
-- v3.0 : Excalibur ARM version 
-- v2.8 : Instantiating dual-port ram in stead of inferring
-- v2.5 : Fixed problem with line buffer fifo status bits
-- v2.3 : Added line missed and new line status bits
-- v2.2 : Implemented native fifos and dpram
-- v2.1 : Added vsync state machine for better timing result
-- v2.0 : Modified for Nios 2.0 
-- v1.1 : Changed DAC mode
-- v1.0 : Added resolution, hsync and vsync timing registers
-- v0.9 : Added internal reset_int signal
-- v0.5 : Added two line buffers to solve bandwidth issue 
-- v0.1 : Initial version
---------------------------------
-- The Lancelot consists of two main state machines, two fifo's and one dual-ported ram.
-- The two state machines are responsable for the hsync, vsync timing and controlling the fifo's.
-- After activating the dma request line, DMA controller will AVALON_SLAVE_WR video data in the first line buffer. 
-- At the same time video data is read out from the second line buffer and feed to the colour table.
-- If the first line buffer is full and the second is empty, then the line buffers are swapped and the process repeats.

-----
-- Library
-----
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;

-----
-- Entity
-----
ENTITY lancelot_vga IS
	PORT
	(
		RESET					: IN std_logic;
		VIDEO_CLK 				: IN std_logic;
		AVALON_CLK				: IN std_logic;
	
	-- Avalon Master Port
		AVALON_MASTER_ADDR		: OUT std_logic_vector(31 DOWNTO 0);
		AVALON_MASTER_DATA_IN	: IN std_logic_vector(31 DOWNTO 0);
		AVALON_MASTER_RD		: OUT std_logic;
		AVALON_MASTER_WAITREQ	: IN std_logic;
		AVALON_MASTER_LOCK	: OUT std_logic;
	
	-- Avalon Slave Port	
		AVALON_SLAVE_CS			: IN std_logic;
		AVALON_SLAVE_ADDR		: IN std_logic_vector(2 DOWNTO 0);
		AVALON_SLAVE_DATA_OUT	: OUT std_logic_vector(31 DOWNTO 0);
		AVALON_SLAVE_DATA_IN 	: IN std_logic_vector(31 DOWNTO 0);
		AVALON_SLAVE_RD			: IN std_logic;
		AVALON_SLAVE_WR			: IN std_logic;
		
	-- Analog Video 
		R, G, B					: OUT std_logic_vector(7 DOWNTO 0);
		HS, VS 					: OUT std_logic;
		M1, M2 					: OUT std_logic;
		BLANK_N 				: OUT std_logic;
		SYNC_N					: OUT std_logic;
		SYNC_T 					: OUT std_logic
	);
END lancelot_vga;

-----
-- Architecture
-----
ARCHITECTURE behavior OF lancelot_vga IS

---
-- Components
---
COMPONENT lancelot_fifo 
	GENERIC
	(
		fifo_depth 							: natural;
		fifo_width 							: natural 		
	);
	PORT
	(
		rst, wprst, rprst					: IN std_logic;
		wrclk, rdclk						: IN std_logic;
		wrreq, rdreq						: IN std_logic;
		wrdata								: IN std_logic_vector(fifo_width - 1 DOWNTO 0);
		rddata								: OUT std_logic_vector(fifo_width - 1 DOWNTO 0);
		wptop, wpbottom, rptop, rpbottom 	: OUT std_logic;
		line_length							: IN std_logic_vector(10 DOWNTO 0)
	);
END COMPONENT;

COMPONENT lancelot_dpram_256x24
	PORT
	(
		data		: IN STD_LOGIC_VECTOR (23 DOWNTO 0);
		wraddress	: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		rdaddress	: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		wren		: IN STD_LOGIC  := '1';
		wrclock		: IN STD_LOGIC ;
		rdclock		: IN STD_LOGIC ;
		q			: OUT STD_LOGIC_VECTOR (23 DOWNTO 0)
	);
END COMPONENT;

---
-- State Machines
---

-- Hsync State Machine
TYPE hsync_state_type IS 
	(
		hsync_reset,  
		hsync_front_porch, hsync_front_porch1, 
		hsync_pulse, hsync_pulse1, 
		hsync_back_porch, hsync_back_porch1, 
		hsync_active_video1, hsync_active_video2, hsync_active_video3, hsync_active_video4, 
		hsync_blank, hsync_blank1,
		hsync_line_missed
	);  
SIGNAL hsync_current_state, hsync_next_state : hsync_state_type; 

-- Vsync State Machine
TYPE vsync_state_type IS 
	(
		vsync_reset, 
		vsync_front_porch, 
		vsync_pulse, 
		vsync_back_porch, 
		vsync_active_video
	);
SIGNAL vsync_current_state, vsync_next_state : vsync_state_type; 

-- DMA State Machine
TYPE dma_state_type IS 
	(
		start_dma, 
		clear_dma, 
		set_dma
	);
SIGNAL dma_current_state, dma_next_state : dma_state_type;

-- DAC State Machine
TYPE dac_mode_state_type IS 
	(
		ds0, ds1, ds2, ds3, ds4
	);
SIGNAL dac_mode_current_state, dac_mode_next_state : dac_mode_state_type;

-- Avalon Master State Machine
TYPE avalon_master_state_type IS (master_idle, master_request_bus, master_burst, master_release);
SIGNAL avalon_master_current_state, avalon_master_next_state : avalon_master_state_type;

---
-- Signals
---

-- Reset
SIGNAL reset_int				: std_logic;
SIGNAL reset_counter			: INTEGER RANGE 0 TO 15;
SIGNAL reset_reg_sel			: std_logic;

-- Colour Table
SIGNAL colour_table_address 	: std_logic_vector(7 DOWNTO 0);
SIGNAL colour_byte_sel			: INTEGER RANGE 0 TO 3;
SIGNAL colour_byte_sel_int		: INTEGER RANGE 0 TO 3;
SIGNAL colour_byte_sel0			: INTEGER RANGE 0 TO 3;
SIGNAL colour_byte_sel1			: INTEGER RANGE 0 TO 3;
SIGNAL colour_byte_sel2			: INTEGER RANGE 0 TO 3;
SIGNAL colour_byte_sel3  		: INTEGER RANGE 0 TO 3;
SIGNAL colour_table_wr 			: std_logic;
SIGNAL colour_table_reg_sel 	: std_logic;

-- Line Buffer 
SIGNAL line_buffer_wr1 			: std_logic; 
SIGNAL line_buffer_wr2 			: std_logic; 
SIGNAL line_buffer_reg_sel 		: std_logic; 
SIGNAL line_buffer_data_in		: std_logic_vector(31 DOWNTO 0); 
SIGNAL line_buffer_data1		: std_logic_vector(31 DOWNTO 0); 
SIGNAL line_buffer_data2		: std_logic_vector(31 DOWNTO 0);
SIGNAL video_data 				: std_logic_vector(31 DOWNTO 0);
SIGNAL line_buffer_dma_empty	: std_logic; 
SIGNAL line_buffer_dma_full		: std_logic; 
SIGNAL line_buffer_video_empty	: std_logic; 
SIGNAL line_buffer_video_full 	: std_logic;
SIGNAL line_buffer_rd1			: std_logic; 
SIGNAL line_buffer_rd2			: std_logic;
SIGNAL line_buffer_rd  			: std_logic;
SIGNAL line_buffer_toggle 		: std_logic;
SIGNAL line_buffer_sel 			: INTEGER RANGE 0 TO 1;
SIGNAL line_buffer_rptop1		: std_logic;
SIGNAL line_buffer_rpbottom1	: std_logic; 
SIGNAL line_buffer_wptop1		: std_logic; 
SIGNAL line_buffer_wpbottom1 	: std_logic;
SIGNAL line_buffer_rptop2		: std_logic; 
SIGNAL line_buffer_rpbottom2	: std_logic; 
SIGNAL line_buffer_wptop2		: std_logic; 
SIGNAL line_buffer_wpbottom2 	: std_logic;
SIGNAL line_begin, line_end 	: std_logic;
SIGNAL line_buffer_wprst1		: std_logic; 
SIGNAL line_buffer_wprst2		: std_logic; 
SIGNAL line_buffer_rprst1		: std_logic; 
SIGNAL line_buffer_rprst2 		: std_logic;
SIGNAL line_length 				: std_logic_vector(10 DOWNTO 0);
SIGNAL line_missed			: std_logic;

-- Pixel Counter
SIGNAL pixel_counter_data 		: INTEGER RANGE 0 TO 1024;
SIGNAL pixel_counter_load 		: std_logic;
SIGNAL pixel_counter_zero 		: std_logic;

-- Vsync Counter
SIGNAL vsync_counter_reset 		: std_logic;
SIGNAL vsync_counter_inc 		: std_logic;
SIGNAL vsync_counter			: INTEGER RANGE 0 TO 1024; 
SIGNAL vsync_top1				: INTEGER RANGE 0 TO 1024;
SIGNAL vsync_top2				: INTEGER RANGE 0 TO 1024;
SIGNAL vsync_bottom				: INTEGER RANGE 0 TO 1024;

-- Control Register
SIGNAL control_reg 				: std_logic_vector(31 DOWNTO 0); 
SIGNAL status_reg 				: std_logic_vector(31 DOWNTO 0);
SIGNAL control_reg_sel 			: std_logic;
SIGNAL control_reg_wr 			: std_logic;
ALIAS start_video 				: std_logic IS control_reg(2);
ALIAS dac_mode 					: std_logic IS control_reg(3);
ALIAS hsync_pol 				: std_logic IS control_reg(4);
ALIAS vsync_pol 				: std_logic IS control_reg(5);
ALIAS force_blanking				: std_logic IS control_reg(6);

-- Video Signals
SIGNAL hs_int					: std_logic;
SIGNAL vs_int					: std_logic;
SIGNAL blank_hs					: std_logic;
SIGNAL blank_vs 				: std_logic;
SIGNAL blank_int 				: std_logic;
SIGNAL blank_int1				: std_logic;
SIGNAL blank0					: std_logic;
SIGNAL blank1 					: std_logic;
SIGNAL blank2					: std_logic;
SIGNAL blank3					: std_logic;
SIGNAL blank4 					: std_logic;
SIGNAL rgb 						: std_logic_vector(23 DOWNTO 0);

-- Resolution Register
SIGNAL resolution_reg 			: std_logic_vector(31 DOWNTO 0);
SIGNAL resolution_reg_sel 		: std_logic;
SIGNAL resolution_reg_wr 		: std_logic;
SIGNAL horizontal_resolution 	: INTEGER RANGE 0 TO 1024;
SIGNAL vertical_resolution 		: INTEGER RANGE 0 TO 1024;

-- Hsync Timing Register
SIGNAL hsync_timing_reg 		: std_logic_vector(31 DOWNTO 0);
SIGNAL hsync_timing_reg_sel 	: std_logic;
SIGNAL hsync_timing_reg_wr 		: std_logic;
SIGNAL hsync_pulse_width 		: INTEGER RANGE 0 TO 255;
SIGNAL hsync_back_porch_width 	: INTEGER RANGE 0 TO 255;
SIGNAL hsync_front_porch_width 	: INTEGER RANGE 0 TO 255;

-- Vsync Timing Register
SIGNAL vsync_timing_reg 		: std_logic_vector(31 DOWNTO 0);
SIGNAL vsync_timing_reg_sel 	: std_logic;
SIGNAL vsync_timing_reg_wr 		: std_logic;
SIGNAL vsync_pulse_width 		: INTEGER RANGE 0 TO 255; 
SIGNAL vsync_back_porch_width 	: INTEGER RANGE 0 TO 255;
SIGNAL vsync_front_porch_width 	: INTEGER RANGE 0 TO 255;	

-- DMA 
SIGNAL dma_address_reg 			: std_logic_vector(31 DOWNTO 0);
SIGNAL dma_address_reg_sel 		: std_logic;
SIGNAL dma_address_reg_wr 		: std_logic;
SIGNAL video_dma_first 			: std_logic; 
SIGNAL video_dma_request 		: std_logic;
SIGNAL avalon_dma_first 		: std_logic; 
SIGNAL avalon_dma_request 		: std_logic;
SIGNAL dma_address_load			: std_logic;
SIGNAL dma_address_inc			: std_logic;
SIGNAL dma_address_dec			: std_logic;
SIGNAL dma_transfer_begin		: std_logic;
SIGNAL dma_transfer_end 		: std_logic;
SIGNAL dma_write				: std_logic;
SIGNAL dma_request				: std_logic;
SIGNAL dma_first				: std_logic;
SIGNAL dma_address 				: std_logic_vector(31 DOWNTO 0);
SIGNAL dma_count 				: integer RANGE 0 TO 1024;

BEGIN

colour_table : lancelot_dpram_256x24 
	PORT MAP 
	(
		data		=> AVALON_SLAVE_DATA_IN(23 DOWNTO 0),
		wraddress	=> AVALON_SLAVE_DATA_IN(31 DOWNTO 24),
		rdaddress 	=> colour_table_address,
		wren	 	=> colour_table_wr,
		wrclock	 	=> AVALON_CLK,
		rdclock	 	=> video_clk,
		q	 		=> rgb
	);
		
line_buffer1 : lancelot_fifo	
	GENERIC MAP
	(
		fifo_depth => 160,
		fifo_width => 32
	)
	PORT MAP
	(
		rst			=> reset_int,
		wprst		=> line_buffer_wprst1,
		rprst		=> line_buffer_rprst1,
		wrclk 		=> AVALON_CLK,
		rdclk 		=> video_clk,
		wrreq 		=> line_buffer_wr1,
		rdreq 		=> line_buffer_rd1,
		wrdata 		=> line_buffer_data_in,
		rddata		=> line_buffer_data1,
		wptop 		=> line_buffer_wptop1,
		wpbottom 	=> line_buffer_wpbottom1,
		rptop 		=> line_buffer_rptop1,
		rpbottom 	=> line_buffer_rpbottom1,
		line_length	=> line_length
	);

		
line_buffer2 : lancelot_fifo	
	GENERIC MAP
	(
		fifo_depth => 160,
		fifo_width => 32
	)
	PORT MAP
	(
		rst			=> reset_int,
		wprst		=> line_buffer_wprst2,
		rprst		=> line_buffer_rprst2,
		wrclk 		=> AVALON_CLK,
		rdclk 		=> video_clk,
		wrreq 		=> line_buffer_wr2,
		rdreq 		=> line_buffer_rd2,
		wrdata 		=> line_buffer_data_in,
		rddata		=> line_buffer_data2,
		wptop 		=> line_buffer_wptop2,
		wpbottom 	=> line_buffer_wpbottom2,
		rptop 		=> line_buffer_rptop2,
		rpbottom 	=> line_buffer_rpbottom2,
		line_length	=> line_length
	);	

line_buffer_data_in <= AVALON_MASTER_DATA_IN; 

-------------------
-- Avalon Master --
-------------------
-- The Avalon master reads video data from the external SDRAM and stores it in the Lancelot FIFO's 

PROCESS(AVALON_CLK, reset_int)
BEGIN
	IF reset_int = '1' THEN
		avalon_master_current_state <= master_idle;
	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		avalon_master_current_state <= avalon_master_next_state AFTER 5 ns;
	END IF;
END PROCESS;


PROCESS(avalon_master_current_state, dma_request, dma_address, dma_first, dma_transfer_end, AVALON_MASTER_WAITREQ)
BEGIN

	AVALON_MASTER_ADDR 	<= (others => '0');
	AVALON_MASTER_RD	<= '0';
	dma_address_load 	<= '0';
	dma_address_inc 	<= '0';
	dma_address_dec 	<= '0'; 
	dma_transfer_begin 	<= '0';
	dma_write 			<= '0';
	AVALON_MASTER_LOCK <= '0';
	
	CASE avalon_master_current_state IS

		WHEN master_idle =>
			IF dma_request = '1' THEN
				avalon_master_next_state <= master_request_bus;
			ELSE
				avalon_master_next_state <= master_idle;
			END IF;

		WHEN master_request_bus =>
			dma_transfer_begin <= '1';
			IF dma_first = '1' THEN
				dma_address_load <= '1';
			END IF;
			avalon_master_next_state <= master_burst;
								
		WHEN master_burst =>
			AVALON_MASTER_ADDR <= dma_address;
			AVALON_MASTER_RD <= '1';
			AVALON_MASTER_LOCK <= '1';
			IF AVALON_MASTER_WAITREQ = '1' THEN
				avalon_master_next_state <= master_burst;
			ELSE
				dma_address_inc <= '1';
				dma_write <= '1';
				IF dma_transfer_end = '0' THEN
					avalon_master_next_state <= master_burst;	
				ELSE
					avalon_master_next_state <= master_release;
				END IF;
			END IF;
		
		WHEN master_release =>
			AVALON_MASTER_ADDR <= dma_address;
			AVALON_MASTER_RD <= '1';
			avalon_master_next_state <= master_idle;	
				
		WHEN others =>
			avalon_master_next_state <= master_idle;
		
	END CASE;
	
END PROCESS;

-- DMA address register
PROCESS(AVALON_CLK, reset_int, dma_address_load, dma_address_inc, dma_address_dec, dma_address_reg)
BEGIN

	IF reset_int = '1' THEN
		dma_address <= (others => '0');
	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN

⌨️ 快捷键说明

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