📄 vga.vhd
字号:
--------------------------------------------------------------------
-- Company : XESS Corp.
-- Engineer : Dave Vanden Bout
-- Creation Date : 05/17/2005
-- Copyright : 2005, XESS Corp
-- Tool Versions : WebPACK 6.3.03i
--
-- Description:
-- VGA generator that displays pixels on a VGA monitor.
--
-- Revision:
-- 1.1.0
--
-- Additional Comments:
-- 1.1.0:
-- The description of the input buffer FIFO was moved into a
-- separate file.
-- 1.0.0:
-- Initial release.
--
-- License:
-- This code can be freely distributed and modified as long as
-- this header is not removed.
--------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
package vga_pckg is
component vga
generic (
FREQ : natural := 50_000; -- master clock frequency (in KHz)
CLK_DIV : natural := 1; -- FREQ / CLK_DIV = pixel clock
PIXEL_WIDTH : natural := 8; -- pixel width: 1, 2, 4, 8, or 16 bits
PIXELS_PER_LINE : natural := 800; -- pixels per video scan line
LINES_PER_FRAME : natural := 600; -- scan lines per video frame
NUM_RGB_BITS : natural := 2; -- width of R, G and B color output buses (2 or 3 are only valid values)
FIT_TO_SCREEN : boolean := true -- fit width x length to monitor screen
);
port (
rst : in std_logic; -- reset
clk : in std_logic; -- master clock
wr : in std_logic; -- write-enable for pixel buffer
pixel_data_in : in std_logic_vector(15 downto 0); -- input databus to pixel buffer
full : out std_logic; -- pixel buffer full
eof : out std_logic; -- end of vga frame
r, g, b : out std_logic_vector(NUM_RGB_BITS-1 downto 0); -- R,G,B color output buses
hsync_n : out std_logic; -- horizontal sync pulse
vsync_n : out std_logic; -- vertical sync pulse
blank : out std_logic -- blanking signal
);
end component vga;
end package vga_pckg;
library IEEE, unisim;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_unsigned.all;
use unisim.vcomponents.all;
use work.fifo_pckg.all;
use work.common.all;
entity vga is
generic (
FREQ : natural := 50_000; -- master clock frequency (in KHz)
CLK_DIV : natural := 1; -- FREQ / CLK_DIV = pixel clock
PIXEL_WIDTH : natural := 4; -- pixel width: 1, 2, 4, 8, or 16 bits
PIXELS_PER_LINE : natural := 1024; -- pixels per video scan line
LINES_PER_FRAME : natural := 512; -- scan lines per video frame
NUM_RGB_BITS : natural := 2; -- width of R, G and B color output buses
FIT_TO_SCREEN : boolean := true -- fit width x length to monitor screen
);
port (
rst : in std_logic; -- reset
clk : in std_logic; -- master clock
wr : in std_logic; -- write-enable for pixel buffer
pixel_data_in : in std_logic_vector(15 downto 0); -- input databus to pixel buffer
full : out std_logic; -- pixel buffer full
eof : out std_logic; -- end of vga frame
r, g, b : out std_logic_vector(NUM_RGB_BITS-1 downto 0); -- R,G,B color output buses
hsync_n : out std_logic; -- horizontal sync pulse
vsync_n : out std_logic; -- vertical sync pulse
blank : out std_logic -- blanking signal
);
end entity vga;
architecture vga_arch of vga is
constant NORM : natural := 1000; -- normalization factor for us * KHz
-- video timing parameters for FIT_TO_SCREEN mode
constant HSYNC_START_F : natural := (NORM * PIXELS_PER_LINE * CLK_DIV)/FREQ + 1; -- start of horiz. sync pulse with a scanline (us)
constant HSYNC_PERIOD_F : natural := HSYNC_START_F + 6; -- horizontal scanline period (us)
constant HSYNC_WIDTH_F : natural := 4; -- width of horiz. sync pulse (us)
constant HSYNC_FREQ_F : natural := NORM / HSYNC_PERIOD_F; -- scanline frequency (KHz)
constant VSYNC_START_F : natural := HSYNC_PERIOD_F * LINES_PER_FRAME + 340; -- start of vert. sync pulse within a frame (us)
constant VSYNC_PERIOD_F : natural := VSYNC_START_F + 1084; -- video frame period (us)
constant VSYNC_WIDTH_F : natural := 64; -- width of vert. sync pulse (us)
-- video timing for 31 KHz horizontal, 60 Hz vertical screen refresh
constant HSYNC_START : natural := 26; -- start of horiz. sync pulse with a scanline (us)
constant HSYNC_PERIOD : natural := 32; -- horizontal scanline period (us)
constant HSYNC_WIDTH : natural := 4; -- width of horiz. sync pulse (us)
constant HSYNC_FREQ : natural := NORM / HSYNC_PERIOD; -- scanline frequency (KHz)
constant VSYNC_START : natural := 15_700; -- start of vert. sync pulse within a frame (us)
constant VSYNC_PERIOD : natural := 16_784; -- video frame period (us)
constant VSYNC_WIDTH : natural := 64; -- width of vert. sync pulse (us)
signal clk_div_cnt : natural range 0 to 255;
signal cke : std_logic;
signal line_cnt, pixel_cnt : std_logic_vector(15 downto 0); -- current video line and pixel within line
signal fifo_rst : std_logic;
signal fifo_level : std_logic_vector(7 downto 0);
signal eof_i, eof_x, eof_r : std_logic;
signal v_gate, cke_v_gate : std_logic;
signal h_blank, v_blank, visible : std_logic;
constant PIX_PROC_DELAY : natural := 3; -- time delay to read a pixel from the FIFO and colormap it
signal hsync_x, hsync_r : std_logic_vector(PIX_PROC_DELAY downto 1);
signal blank_x, blank_r : std_logic_vector(PIX_PROC_DELAY downto 1);
signal cke_rd, rd_x, rd_r : std_logic;
signal pixel : std_logic_vector(PIXEL_WIDTH-1 downto 0);
signal pixel_data_x, pixel_data_r : std_logic_vector(15 downto 0);
signal pixel_data_out : std_logic_vector(15 downto 0);
signal rgb_x, rgb_r : std_logic_vector(3*NUM_RGB_BITS-1 downto 0);
component fifo_cc
port (
clk : in std_logic;
rst : in std_logic;
rd : in std_logic;
wr : in std_logic;
data_in : in std_logic_vector(15 downto 0);
data_out : out std_logic_vector(15 downto 0);
full : out std_logic;
empty : out std_logic;
level : out std_logic_vector(7 downto 0)
);
end component fifo_cc;
component sync
generic (
FREQ : natural := 50_000; -- master clock frequency (in KHz)
PERIOD : natural := 32; -- period of sync pulse (in us)
START : natural := 26; -- time sync pulse starts within the period (in us)
WIDTH : natural := 4; -- width of sync pulse (in us)
VISIBLE : natural := 1024 -- number of visible pixels/line or lines/frame
);
port (
rst : in std_logic; -- reset
clk : in std_logic; -- master clock
cke : in std_logic; -- clock-enable
sync_n : out std_logic; -- sync pulse
gate : out std_logic; -- single-clock pulse at start of sync pulse
blank : out std_logic; -- blanking signal
cnt : out std_logic_vector(15 downto 0) -- output the timing counter value
);
end component sync;
begin
-- clock divider for reducing the pixel clock rate
process(clk, rst)
begin
if rst = YES then
clk_div_cnt <= 0;
cke <= YES;
elsif rising_edge(clk) then
if clk_div_cnt = CLK_DIV-1 then
clk_div_cnt <= 0;
cke <= YES;
else
clk_div_cnt <= clk_div_cnt + 1;
cke <= NO;
end if;
end if;
end process;
-- pixel data buffer
cke_rd <= rd_x and cke;
fifo : fifo_255x16_cc
port map (
clk => clk,
rd => cke_rd,
wr => wr,
data_in => pixel_data_in,
rst => fifo_rst,
data_out => pixel_data_out,
full => open,
empty => open,
level => fifo_level
);
full <= YES when fifo_level(7 downto 3) = "11111" else NO;
-- the clock enable for the vertical sync module is also combined with a gate signal
-- that is generated at the end of every scanline by the horizontal sync module
cke_v_gate <= cke and v_gate;
-- generate the horizontal and vertical sync pulses for FIT_TO_SCREEN mode
gen_syncs_fit : if FIT_TO_SCREEN = true generate
hsync : sync
generic map (
FREQ => FREQ / CLK_DIV, -- master pixel-clock frequency
PERIOD => HSYNC_PERIOD_F, -- scanline period (32 us)
START => HSYNC_START_F, -- start of horizontal sync pulse in scan line
WIDTH => HSYNC_WIDTH_F, -- width of horizontal sync pulse
VISIBLE => PIXELS_PER_LINE
)
port map (
rst => rst,
clk => clk, -- master clock
cke => cke, -- a new pixel is output whenever the clock is enabled
sync_n => hsync_x(1), -- send pulse through delay line
gate => v_gate, -- send gate signal to increment vertical sync pulse generator once per scan line
blank => h_blank, -- blanking signal within a scan line
cnt => pixel_cnt -- current pixel within the scan line
);
vsync : sync
generic map (
FREQ => HSYNC_FREQ_F, -- scanline frequency
PERIOD => VSYNC_PERIOD_F, -- image frame period
START => VSYNC_START_F, -- start of vertical sync pulse in frame
WIDTH => VSYNC_WIDTH_F, -- width of vertical sync pulse
VISIBLE => LINES_PER_FRAME
)
port map (
rst => rst,
clk => clk, -- master clock
cke => cke_v_gate, -- enable clock once per horizontal scan line
sync_n => vsync_n, -- send pulse through delay line
gate => eof_x, -- indicate the end of a complete frame
blank => v_blank, -- blanking signal within a frame
cnt => line_cnt -- current scan line within a frame
);
end generate;
-- generate the horizontal and vertical sync pulses for 31 KHz horizontal, 60 Hz vertical screen refresh
gen_syncs_nofit : if FIT_TO_SCREEN = false generate
hsync : sync
generic map (
FREQ => FREQ / CLK_DIV, -- master pixel-clock frequency
PERIOD => HSYNC_PERIOD, -- scanline period (32 us)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -