📄 vga_display.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 + -