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

📄 lancelot_vga.vhd

📁 基于FPGA的VGA控制器设计。对外支持普通VGA接口
💻 VHD
📖 第 1 页 / 共 3 页
字号:

		IF dma_address_load = '1' THEN
			dma_address <= dma_address_reg;
		ELSE
		
			IF dma_address_inc = '1' THEN
				dma_address <= dma_address + "100";
			END IF;
			IF dma_address_dec = '1' THEN
				dma_address <= dma_address - "100";
			END IF;
		END IF;		
	END IF;

END PROCESS;

-- DMA length counter
PROCESS(AVALON_CLK, reset_int, dma_address_inc, dma_address_dec, dma_transfer_begin)
BEGIN

	IF reset_int = '1' THEN
		dma_count <= 0;
		dma_transfer_end <= '0';
	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		IF dma_transfer_begin = '1' THEN
			dma_count <= 0;
			dma_transfer_end <= '0';
		ELSE
			IF dma_address_inc = '1' THEN
				dma_count <= dma_count + 4;			
			END IF;
			IF dma_address_dec = '1' THEN
				dma_count <= dma_count - 4;			
			END IF;
		END IF;	
		
		IF dma_count = horizontal_resolution - 4 THEN
			dma_transfer_end <= '1';
		END IF;
	
	END IF;

END PROCESS;

-- Transfer DMA signals from video domain to Avalon domain
PROCESS(AVALON_CLK, reset_int, video_dma_first, video_dma_request)
BEGIN
	IF reset_int = '1' THEN
 		avalon_dma_first 	<= '0';
		avalon_dma_request 	<= '0';
		dma_first 			<= '0';
		dma_request 		<= '0';
		
	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		avalon_dma_first 	<= video_dma_first;
		avalon_dma_request 	<= video_dma_request;
		dma_first 		<= avalon_dma_first;
		dma_request 		<= avalon_dma_request;
	END IF;

END PROCESS;

----------------------------------
-- Video DAC Mode state machine --
----------------------------------
-- Set DAC in RGB mode and bias on all three channels
 
PROCESS(VIDEO_CLK, reset_int)
BEGIN
	IF reset_int = '1' THEN
		dac_mode_current_state <= ds0;
	ELSIF (VIDEO_CLK'event AND VIDEO_CLK = '0') THEN
		dac_mode_current_state <= dac_mode_next_state AFTER 5 ns;
	END IF;
END PROCESS;

PROCESS(dac_mode_current_state, control_reg)
BEGIN

	sync_n	<= '0';
	m2		<= '0';
	m1		<= '0';
	sync_t 	<= '0';

	
	CASE dac_mode_current_state IS 

		WHEN ds0 =>
			IF dac_mode = '1' THEN
				dac_mode_next_state <= ds1;
			ELSE
				dac_mode_next_state <= ds0;
			END IF;
			
		WHEN ds1 =>
 			sync_n	<= '1';
			m2		<= '0';
 			m1		<= '0';
			sync_t 	<= '0';
			dac_mode_next_state <= ds2;

		-- Bias on all three channels
	   	WHEN ds2 =>
			sync_n	<= '0';
			m2		<= '1';
			m1		<= '0';
			sync_t 	<= '0';
			dac_mode_next_state <= ds3;

		WHEN ds3 =>
			sync_n	<= '0';
			m2		<= '1';
			m1		<= '0';
			sync_t 	<= '0';
			dac_mode_next_state <= ds4;

		-- RGB Mode
		WHEN ds4 =>
			sync_n	<= '1';
			m2		<= '0';
			m1		<= '0';
			sync_t 	<= '0';
			dac_mode_next_state <= ds4;
	
		WHEN others =>
			sync_n	<= '1';
			m2		<= '0';
			m1		<= '0';
			sync_t 	<= '0';
			dac_mode_next_state <= ds0;

	END CASE;

END PROCESS;

--------------------------
-- Buffer video signals --
--------------------------
PROCESS(VIDEO_CLK, reset_int)
BEGIN
	IF reset_int = '1' THEN
		r 		<= (others => '0');
		g 		<= (others => '0');
		b 		<= (others => '0');
		hs 		<= '1';
		vs 		<= '1';
		blank_n <= '0';
	ELSIF (VIDEO_CLK'event AND VIDEO_CLK = '1') THEN 
		r 		<= rgb(23 DOWNTO 16);
		g 		<= rgb(15 DOWNTO 8);
		b 		<= rgb(7 DOWNTO 0);
	
		IF hsync_pol = '1' THEN
			hs 	<= not hs_int;
		ELSE
			hs 	<= hs_int;
		END IF;

		IF vsync_pol = '1' THEN
			vs 	<= not vs_int;
		ELSE
			vs 	<= vs_int;
		END IF;
	
		blank_n <= blank_int;
	END IF;
END PROCESS;

-----------------
-- Blank delay --
-----------------
-- The blank signal must be delayed for one video clk because of colour table registered inputs and outputs  
PROCESS(VIDEO_CLK, reset_int, blank_vs, blank_hs)
BEGIN
	IF reset_int = '1' THEN
		blank_int 	<= '0';
		blank_int1 	<= '0';
		blank4 		<= '0';
		blank3 		<= '0';
		blank2 		<= '0';
		blank1 		<= '0';
		blank0 		<= '0';
	ELSIF (VIDEO_CLK'event AND VIDEO_CLK = '1') THEN
		IF (blank_vs = '1' AND blank_hs = '1') THEN
			blank_int1 <= '1';
		ELSE
			blank_int1 <= '0';
		END IF;
		
		blank_int 	<= blank4;
		blank4		<= blank3;
		blank3 		<= blank2;
		blank2 		<= blank1;
		blank1 		<= blank0;
		blank0 		<= blank_int1;

	END IF;
END PROCESS;

-------------------------------
-- Avalon Select Generation --
-------------------------------
-- Avalon Memory Map
-------------------------------
-- 0 : Control / Status Register		
-- 1 : Colour Tabel
-- 2 : Line Buffer
-- 3 : Reset Register
-- 4 : Resolution Register
-- 5 : Hsync Timing Register
-- 6 : VSync Timing Register
-- 7 : DMA Register
-------------------------------
control_reg_sel			<= '1' WHEN AVALON_SLAVE_CS = '1' AND AVALON_SLAVE_ADDR = "000" ELSE '0';
colour_table_reg_sel	<= '1' WHEN AVALON_SLAVE_CS = '1' AND AVALON_SLAVE_ADDR = "001" ELSE '0';
line_buffer_reg_sel		<= '1' WHEN AVALON_SLAVE_CS = '1' AND AVALON_SLAVE_ADDR = "010" ELSE '0';
reset_reg_sel			<= '1' WHEN AVALON_SLAVE_CS = '1' AND AVALON_SLAVE_ADDR = "011" ELSE '0';
resolution_reg_sel		<= '1' WHEN AVALON_SLAVE_CS = '1' AND AVALON_SLAVE_ADDR = "100" ELSE '0';
hsync_timing_reg_sel	<= '1' WHEN AVALON_SLAVE_CS = '1' AND AVALON_SLAVE_ADDR = "101" ELSE '0';
vsync_timing_reg_sel	<= '1' WHEN AVALON_SLAVE_CS = '1' AND AVALON_SLAVE_ADDR = "110" ELSE '0';
dma_address_reg_sel		<= '1' WHEN AVALON_SLAVE_CS = '1' AND AVALON_SLAVE_ADDR = "111" ELSE '0';

------------------------------
-- Avalon Strobe Generation --
------------------------------
control_reg_wr		<= '1' WHEN control_reg_sel = '1' AND AVALON_SLAVE_WR = '1' ELSE '0';
colour_table_wr		<= '1' WHEN colour_table_reg_sel = '1' AND AVALON_SLAVE_WR = '1' ELSE '0';
line_buffer_wr1		<= '1' WHEN (dma_write = '1' AND line_buffer_sel = 1) ELSE '0';
line_buffer_wr2		<= '1' WHEN (dma_write = '1' AND line_buffer_sel = 0) ELSE '0';
resolution_reg_wr	<= '1' WHEN resolution_reg_sel = '1' AND AVALON_SLAVE_WR = '1' ELSE '0';
hsync_timing_reg_wr	<= '1' WHEN hsync_timing_reg_sel = '1' AND AVALON_SLAVE_WR = '1' ELSE '0';
vsync_timing_reg_wr	<= '1' WHEN vsync_timing_reg_sel = '1' AND AVALON_SLAVE_WR = '1' ELSE '0';
dma_address_reg_wr	<= '1' WHEN dma_address_reg_sel = '1' AND AVALON_SLAVE_WR = '1' ELSE '0';

----------------------------
-- Avalon Data output mux -- 
----------------------------
AVALON_SLAVE_DATA_OUT	<=	status_reg			WHEN control_reg_sel = '1' 		AND AVALON_SLAVE_RD = '1' ELSE
							resolution_reg 		WHEN resolution_reg_sel = '1' 	AND AVALON_SLAVE_RD = '1' ELSE
							hsync_timing_reg	WHEN hsync_timing_reg_sel = '1' AND AVALON_SLAVE_RD = '1' ELSE
							vsync_timing_reg 	WHEN vsync_timing_reg_sel = '1' AND AVALON_SLAVE_RD = '1' ELSE
							dma_address_reg 	WHEN dma_address_reg_sel = '1' 	AND AVALON_SLAVE_RD = '1' ELSE
							(others => '0');

-----------------------------------
-- Control Register (AVALON_SLAVE_WR only) --
-----------------------------------
-- 6 : Force Blanking
-- 5 : Polarity vsync
-- 4 : Polarity hsync
-- 3 : Set DAC mode
-- 2 : Start Video 
-- 1 : -
-- 0 : -
-----------------------------------
PROCESS(AVALON_CLK, reset_int, control_reg_wr)
BEGIN
	IF reset_int = '1' THEN
		control_reg <= (others => '0');
	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		IF control_reg_wr = '1' THEN
			control_reg <= AVALON_SLAVE_DATA_IN;
		END IF;
	END IF;
END PROCESS;

-- Reset Generator
-- This self clearing reset_int circuit is triggered by writing to the reset_int register.
PROCESS(RESET, AVALON_CLK, reset_reg_sel, AVALON_SLAVE_DATA_IN, AVALON_SLAVE_WR) 
BEGIN
	IF RESET = '1' THEN
		reset_counter <= 0;
		reset_int <= '1';
	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		IF (reset_reg_sel = '1' AND AVALON_SLAVE_WR = '1' AND AVALON_SLAVE_DATA_IN = x"12345678") THEN
			reset_counter <= 15;
			reset_int <= '1';
		ELSIF reset_counter = 0 THEN
			reset_int <= '0';
		ELSE
			reset_counter <= reset_counter - 1;
			reset_int <= '1';
		END IF; 
	END IF; 
END PROCESS;
---------------------------------
-- Status Register (read only) --
---------------------------------
-- 31 - 16	: MG
-- 9		: New frame
-- 8 		: Line missed
-- 7		: Line buffer video full
-- 6		: Line buffer video empty
-- 5		: Line buffer dma full
-- 4		: Line buffer dma empty
-- 3		: Blank vs
-- 2 		: Blank hs
-- 1 		: Vertical Sync
-- 0 		: Horizontal Sync 
---------------------------------
PROCESS(AVALON_CLK, reset_int, hs_int, vs_int, blank_vs, blank_hs, line_buffer_dma_empty, line_buffer_dma_full, line_buffer_video_empty, line_buffer_video_full)
BEGIN
	IF reset_int = '1' THEN
		status_reg <= (others => '0');
	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		status_reg(31 DOWNTO 16) <= x"5247";
		status_reg(15 DOWNTO 9) <= (others => '0');
		status_reg(8) <= line_missed;
		status_reg(7) <= line_buffer_video_full;
		status_reg(6) <= line_buffer_video_empty;
		status_reg(5) <= line_buffer_dma_full;
		status_reg(4) <= line_buffer_dma_empty;
		status_reg(3) <= blank_vs;
		status_reg(2) <= blank_hs;
		status_reg(1) <= vs_int;
		status_reg(0) <= hs_int;
	END IF;
END PROCESS;

------------------------------
-- Resolution Register (rw) --
------------------------------
-- 26 - 16	: Horizontal resolution
-- 9 - 0 	: Vertical resolution
------------------------------
PROCESS(AVALON_CLK, reset_int, resolution_reg_wr, AVALON_SLAVE_DATA_IN)
BEGIN
	IF reset_int = '1' THEN
		resolution_reg <= (others => '0');
   	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		IF resolution_reg_wr = '1' THEN
			resolution_reg <= AVALON_SLAVE_DATA_IN;
		END IF;
  	END IF;
END PROCESS;
horizontal_resolution	<= conv_integer(resolution_reg(26 DOWNTO 16));
vertical_resolution 	<= conv_integer(resolution_reg(9 DOWNTO 0));
line_length 			<= resolution_reg(26 DOWNTO 16);

--------------------------------
-- Hsync Timing Register (rw) --
--------------------------------
PROCESS(AVALON_CLK, reset_int, hsync_timing_reg_wr, AVALON_SLAVE_DATA_IN)
BEGIN
	IF reset_int = '1' THEN
		hsync_timing_reg <= (others => '0');
 	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		IF hsync_timing_reg_wr = '1' THEN
			hsync_timing_reg <= AVALON_SLAVE_DATA_IN;
	 	END IF;
  	END IF;
END PROCESS;
hsync_pulse_width		<= conv_integer(hsync_timing_reg(23 DOWNTO 16));
hsync_back_porch_width	<= conv_integer(hsync_timing_reg(15 DOWNTO 8));
hsync_front_porch_width	<= conv_integer(hsync_timing_reg(7 DOWNTO 0));

--------------------------------
-- Vsync Timing Register (rw) --
--------------------------------
PROCESS(AVALON_CLK, reset_int, vsync_timing_reg_wr, AVALON_SLAVE_DATA_IN)
BEGIN
	IF reset_int = '1' THEN
		vsync_timing_reg <= (others => '0');
  	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		IF vsync_timing_reg_wr = '1' THEN
			vsync_timing_reg <= AVALON_SLAVE_DATA_IN;
		END IF;
 	END IF;
END PROCESS;
vsync_pulse_width		<= conv_integer(vsync_timing_reg(23 DOWNTO 16));
vsync_back_porch_width	<= conv_integer(vsync_timing_reg(15 DOWNTO 8));
vsync_front_porch_width	<= conv_integer(vsync_timing_reg(7 DOWNTO 0));

-----------------------
-- DMA Register (rw) --
-----------------------
PROCESS(AVALON_CLK, reset_int, dma_address_reg_wr, AVALON_SLAVE_DATA_IN)
BEGIN
	IF reset_int = '1' THEN
		dma_address_reg <= (others => '0');
  	ELSIF (AVALON_CLK'event AND AVALON_CLK = '1') THEN
		IF dma_address_reg_wr = '1' THEN
			dma_address_reg <= AVALON_SLAVE_DATA_IN;
		END IF;
 	END IF;
END PROCESS;

-----------------------------
-- line Buffer Output Mux --
-----------------------------
-- 0 - line buffer 1 video out & line buffer 2 dma input
-- 1 - line buffer 2 video out & line buffer 1 dma input

PROCESS(VIDEO_CLK, reset_int, line_buffer_sel) 
BEGIN
	IF reset_int = '1' THEN
		video_data 				<= (others => '0');
		line_buffer_rd1			<= '0';
		line_buffer_rd2 		<= '0';
		line_buffer_video_empty	<= '0'; 
		line_buffer_video_full 	<= '0';
		line_buffer_dma_full 	<= '0'; 
		line_buffer_dma_empty 	<= '0';
		line_buffer_wprst1		<= '0';
		line_buffer_wprst2		<= '0';
		line_buffer_rprst1		<= '0';
		line_buffer_rprst2		<= '0';
	
	ELSIF (VIDEO_CLK'event AND VIDEO_CLK = '1') THEN
	

		IF line_buffer_sel = 0 THEN

		-- line buffer 1 video data out
		-- line buffer 2 dma data in

			video_data 				<= line_buffer_data1;
			line_buffer_rd1			<= line_buffer_rd;
			line_buffer_rd2 		<= '0';
			line_buffer_video_empty <= line_buffer_rptop1; 
			line_buffer_video_full 	<= line_buffer_wptop1;
			line_buffer_dma_full 	<= line_buffer_wptop2; 
			line_buffer_dma_empty 	<= line_buffer_wpbottom2;
			line_buffer_wprst1		<= line_end;
			line_buffer_wprst2		<= '0';
			line_buffer_rprst1		<= line_begin;
			line_buffer_rprst2		<= '0';

		ELSE	

		-- line buffer 1 dma data in
		-- line buffer 2 video data out

			video_data 				<= line_buffer_data2;
			line_buffer_rd1 		<= '0';
			line_buffer_rd2 		<= line_buffer_rd;
			line_buffer_video_empty <= line_buffer_rptop2;
			line_buffer_video_full 	<= line_buffer_wptop2;
			line_buffer_dma_full 	<= line_buffer_wptop1;

⌨️ 快捷键说明

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