📄 vga.vhd
字号:
-- vga controller
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity vga is
Port (
mclk : in std_logic;
data : in std_logic_vector(7 downto 0);
addr : out std_logic_vector(9 downto 0);
rd : out std_logic;
hs : out std_logic;
vs : out std_logic;
red : out std_logic;
grn : out std_logic;
blu : out std_logic);
end vga;
architecture Behavioral of vga is
constant hpixels : std_logic_vector(9 downto 0) := "1100100000"; -- 800 Value of pixels in a horizontal line
constant vlines : std_logic_vector(9 downto 0) := "1000001001"; -- 521 Number of horizontal lines in the display
constant hbp : std_logic_vector(9 downto 0) := "0010010000"; -- 144 Horizontal back porch
constant hfp : std_logic_vector(9 downto 0) := "1100010000"; -- 784 Horizontal front porch
constant vbp : std_logic_vector(9 downto 0) := "0000011111"; -- 31 Vertical back porch
constant vfp : std_logic_vector(9 downto 0) := "0111111111"; -- 511 Vertical front porch
constant xmax : std_logic_vector(9 downto 0) := "1001111111"; -- 639
constant ymax : std_logic_vector(9 downto 0) := "0111011111"; -- 479
signal hc, vc : std_logic_vector(9 downto 0) := "0000000000"; -- These are the Horizontal and Vertical counters
signal clkdiv : std_logic := '0'; -- Clock divider
signal vidon : std_logic := '0'; -- Tells whether or not its ok to display data
signal vsenable : std_logic := '0'; -- Enable for the Vertical counter
signal x, y : std_logic_vector(9 downto 0) := "0000000000"; -- Horizontal and Vertical Coordinates of the spot
signal ycoord : std_logic_vector(9 downto 0) := "0000000000";
begin
--This cuts the 50Mhz clock in half
process(mclk)
begin
if(mclk = '1' and mclk'EVENT) then
clkdiv <= not clkdiv;
end if;
end process;
--Runs the horizontal counter
process(clkdiv)
begin
if(clkdiv = '1' and clkdiv'EVENT) then
if hc = hpixels then --If the counter has reached the end of pixel count
hc <= "0000000000"; --reset the counter
vsenable <= '1'; --Enable the vertical counter to increment
else
hc <= hc + 1; --Increment the horizontal counter
vsenable <= '0'; --Leave the vsenable off
end if;
end if;
end process;
hs <= '1' when hc(9 downto 7) = "000" else '0'; --Horizontal Sync Pulse
process(clkdiv)
begin
if(clkdiv = '1' and clkdiv'EVENT and vsenable = '1') then --Increment when enabled
if vc = vlines then --Reset when the number of lines is reached
vc <= "0000000000";
else
vc <= vc + 1; --Increment the vertical counter
end if;
end if;
end process;
vs <= '1' when vc(9 downto 1) = "000000000" else '0'; --Vertical Sync Pulse
x <= hc - hbp;
y <= vc - vbp;
ycoord <= "0101101111" - data; -- y coord has to be flipped (screen y coordinates increase from top row to bottom row)
grn <= '1' when (y = ycoord and vidon = '1') else '0'; -- traces the signal on the screen
red <= '1' when (y = X"00F0" and vidon = '1') else '0'; -- draws a line which represents signal value '0'
-- blu draws the grid
blu <= '1' when ((y = X"6F" or y = X"9B" or y = X"C5" or y = X"11B" or y = X"146" or y = X"16F" or -- horizontal grid lines
((x = X"27" or x = X"4F" or x = X"77" or x = X"9F" or x = X"C7" or x = X"EF" or x = X"117" or
x = X"13F" or x = X"167" or x = X"18F" or x = X"1B7" or x = X"1DF" or x = X"207" or x = X"22F" or x = X"257") -- vertical grid lines
and y > X"6F" and y < X"16F")) and -- these rows represent the minimum and the maximum of the signal
vidon='1' and clkdiv = '1') else '0';
vidon <= '1' when ((hc < hfp) and (hc > hbp) and (vc < vfp) and (vc > vbp)) else '0'; -- enables the spot on the screen
rd <= '1' when (x > 0 and x <= xmax and y > 1 and y <= ymax) else '0'; -- read signal to memory (reads only when inside bounds)
addr <= x; -- the read address is the x coordinate since we have an 8-byte entry for each column on the screen
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -