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

📄 hicolvga.vhd

📁 This is interface VGA with monitor
💻 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 + -