📄 hicolvga.vhd
字号:
-------------------------------------------------------------------------------
-- hicolvga.vhd
--
-- Author(s): Jorgen Peddersen and Ashley Partis
-- Created: Jan 2001
-- Last Modified: Jan 2001
--
-- This code acts as a top level for the VGA output project. The RAMDAC should
-- be set up to program high colour dual-edged mode. This displays a pattern
-- of horizontal and vertical bands of colour which can have their colour
-- changed and rotated around the screen. Experimentation is the best way to
-- understand what each switch does.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity vga is
port (
clk: in STD_LOGIC; -- clock
rstn: in STD_LOGIC; -- asynchronous active low reset
red: in STD_LOGIC_VECTOR(1 downto 0); -- switches to control the red component of the test pattern
green: in STD_LOGIC_VECTOR(1 downto 0); -- switches to control the green component of the test pattern
blue: in STD_LOGIC_VECTOR(1 downto 0); -- switches to control the blue component of the test pattern
vertRotate: in STD_LOGIC; -- if high, the pattern will rotate vertically
horiRotate: in STD_LOGIC; -- if high, the pattern will rotate horizontally
vertDirection: in STD_LOGIC; -- direction of vertical rotation
horiDirection: in STD_LOGIC; -- direction of horizontal rotation
pixel: out STD_LOGIC_VECTOR (7 downto 0); -- RAMDAC pixel lines
blankn: out STD_LOGIC; -- RAMDAC blank signal
RDn: out STD_LOGIC; -- RAMDAC RDn connection
WRn: out STD_LOGIC; -- RAMDAC WRn connection
RAMDACD: inout STD_LOGIC_VECTOR (7 downto 0); -- RAMDAC data lines
RS: inout STD_LOGIC_VECTOR (2 downto 0); -- RAMDAC RS lines
hsync: out STD_LOGIC; -- horizontal sync for monitor
vsync: out STD_LOGIC; -- vertical sync for monitor
triste: out STD_LOGIC; -- signal to tristate ethernet PHY
rramce: out STD_LOGIC; -- right ram chip enable
pixelclk: out STD_LOGIC -- RAMDAC pixel clock
);
end vga;
architecture vga_arch of vga is
-- control VGA signals
component vgacore
generic (
H_SIZE : integer; -- horizontal size of input image, MAX 800
V_SIZE : integer -- vertical size of input image, MAX 600
);
port
(
reset: in std_logic; -- asynchronous active low reset
clock: in std_logic; -- clock
hsyncb: buffer std_logic; -- horizontal (line) sync
vsyncb: out std_logic; -- vertical (frame) sync
latch: out STD_LOGIC; -- latches new rgb value
enable: out STD_LOGIC; -- enable/ground RGB output lines
hloc: out std_logic_vector(9 downto 0); -- horizontal address to be decoded for video RAM
vloc: out std_logic_vector(9 downto 0) -- vertical address to be decoded for video RAM
);
end component;
-- Program the RAMDAC
component prgramdacver2
port (
clk: in STD_LOGIC; -- Clock
rstn: in STD_LOGIC; -- Asynchronous active low reset
start: in STD_LOGIC; -- Start signal
done: out STD_LOGIC; -- Asserted when programming is finished
WRn: out STD_LOGIC; -- Write line to RAMDAC (active low)
RDn: out STD_LOGIC; -- Read line to RAMDAC (active low)
RS: inout STD_LOGIC_VECTOR (2 downto 0); -- Register select lines to the RAMDAC
data: inout STD_LOGIC_VECTOR (7 downto 0) -- Bidirectional data line to RAMDAC
);
end component;
-- State signals
type STATETYPE is (stReset, stWaste1, stWaste2, stWaste3, stWait, stForever);
signal presState: STATETYPE;
-- signals so that hsync and vsync can be read
signal hsyncInt : STD_LOGIC;
signal vsyncInt : STD_LOGIC;
-- signals to cue different processes
signal startProg : STD_LOGIC;
signal startVGA : STD_LOGIC;
signal resetVGA : STD_LOGIC;
signal done : STD_LOGIC;
-- signals to generate test pattern
signal hloc : std_logic_vector(9 downto 0); -- horizontal location of each pixel
signal vloc : std_logic_vector(9 downto 0); -- vertical location of each pixel
signal vertoffset : std_logic_vector(8 downto 0); -- offset for vertical rotation
signal horioffset : std_logic_vector(8 downto 0); -- offset for horizontal rotation
signal vertVal : std_logic_vector(8 downto 0); -- adds offset to pixel location
signal horiVal : std_logic_vector(8 downto 0); -- adds offset to pixel location
signal pixelData : STD_LOGIC_VECTOR(15 downto 0); -- colour to write for each pixel
begin
-- VGA controller
cycler : vgacore
generic map (
H_SIZE => 800,
V_SIZE => 600
)
port map(
reset => resetVGA,
clock => clk,
hsyncb => hsyncInt,
vsyncb => vsyncInt,
latch => open,
enable => blankn,
hloc => hloc,
vloc => vloc
);
-- RAMDAC programmer
RAMDACprog : prgramdacver2 port map (
clk => clk,
rstn => rstn,
start => startProg,
done => done,
WRn => WRn,
RDn => RDn,
RS => RS,
data => RAMDACD
);
-- This is a simple mealy state machine that cues the VGA controller
-- when the RAMDAC is finished programming
process(clk, rstn)
begin
if rstn = '0' then
presState <= stReset;
elsif clk'event AND clk = '1' then
case presState is
when stReset =>
presState <= stWaste1;
when stWaste1 =>
presState <= stWaste2;
when stWaste2 =>
presState <= stWaste3;
when stWaste3 =>
presState <= stWait;
when stWait =>
if done = '0' then
presState <= stWait;
else
presState <= stForever;
end if;
when stForever =>
presState <= stForever;
end case;
end if;
end process;
process(presState)
begin
case presState is
when stReset =>
startProg <= '1';
startVGA <= '0';
when stWaste1 =>
startProg <= '1';
startVGA <= '0';
when stWaste2 =>
startProg <= '1';
startVGA <= '0';
when stWaste3 =>
startProg <= '1';
startVGA <= '0';
when stWait =>
startProg <= '0';
startVGA <= '0';
when stForever =>
startProg <= '0';
startVGA <= '1';
end case;
end process;
-- calculate offsets for data that is rotating. Value will update whenever
-- a new page is called for as it is clocked by vsync.
process(rstn, vsyncInt)
begin
if rstn = '0' then
vertoffset <= "000000000";
horioffset <= "000000000";
elsif vsyncInt'event and vsyncInt = '1' then
-- update vertical counter if required
if vertRotate = '1' then
if vertDirection = '0' then
vertoffset <= vertoffset + 1;
else
vertoffset <= vertoffset - 1;
end if;
end if;
-- update horizontal counter if required
if horiRotate = '1' then
if horiDirection = '0' then
horioffset <= horioffset + 1;
else
horioffset <= horioffset - 1;
end if;
end if;
end if;
end process;
-- Synchronize the horizontal and vertical values with the clock.
process(clk,rstn)
begin
if rstn = '0' then
horival <= (others => '0');
vertval <= (others => '0');
elsif clk'event and clk = '0' then
horiVal <= vloc(8 downto 0) + horioffset;
vertVal <= hloc(8 downto 0) + vertoffset;
end if;
end process;
-- Calculate pixelData. This is the colour programmed into each pixel.
-- By choosing different combinations of the three component colours (red, green and blue)
-- different patterns can be formed. For each colour, the following
-- patterns can be chosen from:
-- Bit 1 Bit 0 Description
-- 0 0 Colour does not contribute to any of the pixels on the screen
-- 0 1 Colour forms a test pattern of 32 scaled vertical bands
-- 1 0 Colour forms a test pattern of 32 scaled horizontal bands
-- 1 1 Every pixel on the screen is given the full value of the colour
-- The three colours can all be used to control the colour components of each pixel
-- so it is possible to combine the values and have something like:
-- Full blue component, horizontal green bands and vertical red bands, or
-- No red component, horizontal blue bands and horizontal green bands
-- (this would appear as horizontal cyan bands) etc.
pixelData(15) <= '0';
process(clk, resetVGA)
begin
if resetVGA = '0' then
pixelData(14 downto 10) <= (others => '0');
elsif clk'event and clk = '1' then
case red is -- choose contribution of red component
when "00" =>
pixelData(14 downto 10) <= "00000";
when "01" =>
pixelData(14 downto 10) <= horiVal(8 downto 4);
when "10" =>
pixelData(14 downto 10) <= vertVal(8 downto 4);
when others =>
pixelData(14 downto 10) <= "11111";
end case;
case green is -- choose contribution of green component
when "00" =>
pixelData(9 downto 5) <= "00000";
when "01" =>
pixelData(9 downto 5) <= horiVal(8 downto 4);
when "10" =>
pixelData(9 downto 5) <= vertVal(8 downto 4);
when others =>
pixelData(9 downto 5) <= "11111";
end case;
case blue is -- choose contribution of blue component
when "00" =>
pixelData(4 downto 0) <= "00000";
when "01" =>
pixelData(4 downto 0) <= horiVal(8 downto 4);
when "10" =>
pixelData(4 downto 0) <= vertVal(8 downto 4);
when others =>
pixelData(4 downto 0) <= "11111";
end case;
end if;
end process;
-- handle dual-edged clock to give correct data to the RAMDAC
pixel <= pixelData(7 downto 0) when clk = '1' else pixelData(15 downto 8);
-- only start VGA after RAMDAC has been programmed
resetVGA <= rstn AND startVGA;
-- pass the outputs out
hsync <= hsyncINT;
vsync <= vsyncINT;
-- Provide 50MHz pixel clock
pixelclk <= clk;
-- turn off the ethernet outputs and the right SRAM bank to avoid contention on the lines
triste <= '1';
rramce <= '1';
end vga_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -