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

📄 vga_display.vhd

📁 VGA模块的VHDL代码和软件驱动
💻 VHD
字号:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity vga_display is
	port
	(
		clk:		in std_logic; -- 25.2MHz
		ena:		in std_logic; -- from vga_ctrl
		data:		in std_logic_vector( 15 downto 0 ); -- from vga_ctrl
		addr:		out std_logic_vector( 16 downto 0 ); -- to vga_ctrl
		read_n:		out std_logic;	-- to vga_ctrl
		be_n:		out std_logic_vector( 1 downto 0 ); -- to vga_ctrl
		inuse:		out std_logic;	-- to vga_ctrl (async)
		scan:		out std_logic;	-- to vga_ctrl (async)
		vga_sync:	out std_logic;	-- to vga
		vga_hsync:	out std_logic;	-- to vga
		vga_vsync:	out std_logic;	-- to vga
		vga_blank:	out std_logic;	-- to vga
		vga_r:		out std_logic_vector( 9 downto 0 ); -- to vga
		vga_g:		out std_logic_vector( 9 downto 0 ); -- to vga
--------------- for debug ---------------------
--		ohodd:		out std_logic;
--		ovodd:		out std_logic;
--		ohscan:		out std_logic;
--		ovscan:		out std_logic;
--		ohcnt:		out integer range 0 to 799;
--		ovcnt:		out integer range 0 to 525;
--		ohaddr:		out std_logic_vector( 9 downto 0 );
--		ovaddr:		out std_logic_vector( 8 downto 0 );
-----------------------------------------------
		vga_b:		out std_logic_vector( 9 downto 0 ) -- to vga
	);
end vga_display;

architecture RTL of vga_display is
	
	constant H_SYNC_CYC:	integer :=	96;
	constant H_SYNC_BACK:	integer :=	48;
	constant H_SYNC_ACT:	integer :=	640;
	constant H_SYNC_FRONT:	integer :=	16;
	constant H_SYNC_TOTAL:	integer :=	H_SYNC_CYC+H_SYNC_BACK+H_SYNC_ACT+H_SYNC_FRONT;

	constant V_SYNC_CYC:	integer :=	2;
	constant V_SYNC_BACK:	integer :=	27;
	constant V_SYNC_ACT:	integer :=	480;
	constant V_SYNC_FRONT:	integer :=	11;
	constant V_SYNC_TOTAL:	integer :=	V_SYNC_CYC+V_SYNC_BACK+V_SYNC_ACT+V_SYNC_FRONT;

	constant X_PRESTART:	integer :=	H_SYNC_CYC+H_SYNC_BACK-1;
	constant X_START:		integer :=	H_SYNC_CYC+H_SYNC_BACK;
	constant X_TAIL:		integer :=	H_SYNC_CYC+H_SYNC_BACK+H_SYNC_ACT-1;
	constant X_END:			integer :=	H_SYNC_CYC+H_SYNC_BACK+H_SYNC_ACT;
	constant Y_START:		integer :=	V_SYNC_CYC+V_SYNC_BACK;
	constant Y_END:			integer :=	V_SYNC_CYC+V_SYNC_BACK+V_SYNC_ACT;
	
	signal hcnt:		integer range 0 to H_SYNC_TOTAL;
	signal vcnt:		integer range 0 to V_SYNC_TOTAL;
	signal vscan:		std_logic;	-- latch
	signal hscan:		std_logic;	-- latch
	signal inuse_r:		std_logic;	-- latch
	signal haddr_r:		integer range 0 to 639;
	signal vaddr_r:		integer range 0 to 479;
	signal haddr:		std_logic_vector( 9 downto 0 );
	signal vaddr:		std_logic_vector( 8 downto 0 );
	
begin
	
	------------------ level 1 --------------------------------
	
	Hcnt_P: process( clk, hcnt )
	begin
		if( rising_edge( clk ) ) then
			if( hcnt < H_SYNC_TOTAL - 1 ) then
				hcnt <= hcnt + 1;
			else
				hcnt <= 0;
			end if;
		end if;
	end process Hcnt_P;
	
	Vcnt_P: process( clk, hcnt, vcnt )
	begin
		if( rising_edge( clk ) ) then
			if( hcnt = 0 ) then
				if( vcnt < V_SYNC_TOTAL - 1 ) then
					vcnt <= vcnt + 1;
				else
					vcnt <= 0;
				end if;
			else
				vcnt <= vcnt;
			end if;
		end if;
	end process Vcnt_P;
	
	
	------------------ level 2 --------------------------------
	
	-- pre
	Hscan_P: process( clk, hcnt, hscan, vscan )
	begin
		if( rising_edge( clk ) ) then
			hscan <= hscan;
			if( hcnt = X_PRESTART ) then
				hscan <= vscan;
			end if;
			if( hcnt = X_TAIL ) then
				hscan <= '0';
			end if;
		end if;
	end process Hscan_P;
	
	-- pre
	Vscan_P: process( clk, vcnt, vscan )
	begin
		if( rising_edge( clk ) ) then
			vscan <= vscan;
			if( vcnt = Y_START ) then
				vscan <= '1';
			end if;
			if( vcnt = Y_END ) then
				vscan <= '0';
			end if;
		end if;
	end process Vscan_P;
	
	Inuse_r_P: process( clk, hcnt, vscan, inuse_r )
	begin
		if( rising_edge( clk ) ) then
			inuse_r <= inuse_r;
			if( hcnt = X_PRESTART - 2 and vscan = '1' ) then
				inuse_r <= '1';
			end if;
			if( hcnt = X_END ) then
				inuse_r <= '0';
			end if;
		end if;
	end process Inuse_r_P;
	
	
	------------------ level 3 --------------------------------
	
	Vga_hsync_P: process( clk, ena, hcnt )
	begin
		if( rising_edge( clk ) ) then
			vga_hsync <= '1';
			if( hcnt < H_SYNC_CYC and ena = '1' ) then
				vga_hsync <= '0';
			end if;
		end if;
	end process Vga_hsync_P;
	
	Vga_vsync_P: process( clk, ena, vcnt )
	begin
		if( rising_edge( clk ) ) then
			vga_vsync <= '1';
			if( vcnt < V_SYNC_CYC and ena = '1' ) then
				vga_vsync <= '0';
			end if;
		end if;
	end process Vga_vsync_P;
	
	Haddr_r_P: process( clk, hscan )
	begin
		if( rising_edge( clk ) ) then
			if( hscan = '1' ) then
				haddr_r <= haddr_r + 1;
			else
				haddr_r <= 0;
			end if;
		end if;
	end process Haddr_r_P;
	
	Vaddr_r_P: process( clk, vscan, hcnt, vaddr_r )
	begin
		if( rising_edge( clk ) ) then
			if( vscan = '1' ) then
				if( hcnt = X_END ) then
					vaddr_r <= vaddr_r + 1;
				else
					vaddr_r <= vaddr_r;
				end if;
			else
				vaddr_r <= 0;
			end if;
		end if;
	end process Vaddr_r_P;
	
	inuse <= inuse_r;
	scan <= vscan;
	
	haddr <= conv_std_logic_vector( haddr_r, haddr'length );
	vaddr <= conv_std_logic_vector( vaddr_r, vaddr'length );
	
	addr <= vaddr( 8 downto 1 ) & haddr( 9 downto 1 );
	read_n <= not hscan;
	be_n <= ( others => '0' );
	
	vga_sync <= '1';
	vga_blank <= hscan;
	
	RGB: process( clk, hscan, data )
	begin
		if( rising_edge( clk ) ) then
			if( hscan = '1' ) then
				vga_b <= data( 4 downto 0 ) & "00000";
				vga_g <= data( 10 downto 5 ) & "0000";
				vga_r <= data( 15 downto 11 ) & "00000";
			else
				vga_b <= ( others => '0' );
				vga_g <= ( others => '0' );
				vga_r <= ( others => '0' );
			end if;
		end if;
	end process RGB;
	
--------------- for debug ---------------------
--	ohodd <= hodd;
--	ovodd <= vodd;
--	ohscan <= hscan;
--	ovscan <= vscan;
--	ohcnt <= hcnt;
--	ovcnt <= vcnt;
--	ohaddr <= haddr;
--	ovaddr <= vaddr;
-----------------------------------------------
	
end RTL;

⌨️ 快捷键说明

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