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

📄 npi_vga.vhd

📁 Genode FX is a composition of hardware and software components that enable the creation of fully fl
💻 VHD
📖 第 1 页 / 共 2 页
字号:
-- Brief  : XIL_NPI VGA controller for displaying a frame buffer on VGA/TFT
-- Author : Matthias Alles
-- Date   : 2007-2008
--
-- The resolution is software controlled.
-- It is intended to be used with a MPMC3 or MPMC4 Memory core as an XIL_NPI component.
-- 32 Bit and 64 Bit NPI interfaces are supported.
-- The color format for one pixel is R=15 downto 11, G=10 downto 6, B=4 downto 0

--
-- Copyright (C) Genode Labs, Feske & Helmuth Systementwicklung GbR
--               http://www.genode-labs.com
--
-- This file is part of the Genode-FX package, which is distributed
-- under the terms of the GNU General Public License version 2.
--

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity npi_vga is
	generic( 
	C_PI_ADDR_WIDTH : integer := 32;  -- fixed for XIL_NPI components
	C_PI_DATA_WIDTH : integer := 32;  
	C_PI_BE_WIDTH   : integer := 4;   
	C_PI_RDWDADDR_WIDTH: integer := 4;-- fixed for XIL_NPI components
	C_NPI_PIXEL_CLK_RATIO : integer := 4
	); 
	Port (
	clk   : in std_logic;
	rst   : in std_logic; -- async reset

	frame_buffer_address : in std_logic_vector(31 downto 0);
	frame_buffer_address_valid : in std_logic;
	background_color : in std_logic_vector(15 downto 0);

	fast_clear_start_address : in std_logic_vector(31 downto 0);
	fast_clear_init          : in std_logic;
	fast_clear_pixels        : in std_logic_vector(18 downto 0);
	fast_clear_done          : out std_logic;

	enable_screen    : in std_logic;
	low_x_resolution : in std_logic;
	low_y_resolution : in std_logic;
	x_res : in unsigned(10 downto 0);
	x_max : in unsigned(10 downto 0);
	hsync_low  : in unsigned(10 downto 0);
	hsync_high : in unsigned(10 downto 0);
	y_res : in  unsigned(9 downto 0);
	y_max : in unsigned(9 downto 0);
	vsync_low  : in unsigned(9 downto 0);
	vsync_high : in unsigned(9 downto 0);

	frame_buffer_size : in unsigned(21 downto 0);
	bgnd_low  : in unsigned(9 downto 0);
	bgnd_high : in unsigned(9 downto 0);

	-- VGA/TFT signals
	tft_lcd_hsync : out std_logic;
	tft_lcd_vsync : out std_logic;
	tft_lcd_r     : out std_logic_vector(4 downto 0);
	tft_lcd_g     : out std_logic_vector(5 downto 0);
	tft_lcd_b     : out std_logic_vector(4 downto 0);
	tft_lcd_de    : out std_logic;
	
	-- MPMC Port Interface - Bus is prefixed with XIL_NPI_ 
	XIL_NPI_Addr : out std_logic_vector(C_PI_ADDR_WIDTH-1 downto 0); 
	XIL_NPI_AddrReq : out std_logic; 
	XIL_NPI_AddrAck : in std_logic; 
	XIL_NPI_RNW : out std_logic; 
	XIL_NPI_Size : out std_logic_vector(3 downto 0); 
	XIL_NPI_InitDone : in std_logic; 
	XIL_NPI_WrFIFO_Data : out std_logic_vector(C_PI_DATA_WIDTH-1 downto 0); 
	XIL_NPI_WrFIFO_BE : out std_logic_vector(C_PI_BE_WIDTH-1 downto 0); 
	XIL_NPI_WrFIFO_Push : out std_logic; 
	XIL_NPI_RdFIFO_Data : in std_logic_vector(C_PI_DATA_WIDTH-1 downto 0); 
	XIL_NPI_RdFIFO_Pop : out std_logic; 
	XIL_NPI_RdFIFO_RdWdAddr: in std_logic_vector(C_PI_RDWDADDR_WIDTH-1 downto 0); 
	XIL_NPI_WrFIFO_AlmostFull: in std_logic; 
	XIL_NPI_WrFIFO_Flush: out std_logic; 
--	XIL_NPI_RdFIFO_DataAvailable: in std_logic;   -- removed in mpmc3!!
	XIL_NPI_RdFIFO_Empty: in std_logic; 
	XIL_NPI_RdFIFO_Latency: in std_logic_vector(1 downto 0);
	XIL_NPI_RdFIFO_Flush: out std_logic 
);
end npi_vga;

architecture rtl of npi_vga is

	component vga_timing
	generic(
		C_NPI_PIXEL_CLK_RATIO : integer
	);
	port(
		clk   : in std_logic;
		rst   : in std_logic;
		run   : in std_logic;
		hsync : out std_logic;
		vsync : out std_logic;
		blank : out std_logic;
		frame : out std_logic;
		x_res : in unsigned(10 downto 0);
		x_max : in unsigned(10 downto 0);
		hsync_low  : in unsigned(10 downto 0);
		hsync_high : in unsigned(10 downto 0);
		y_res : in  unsigned(9 downto 0);
		y_max : in unsigned(9 downto 0);
		vsync_low  : in unsigned(9 downto 0);
		vsync_high : in unsigned(9 downto 0);
		x     : out std_logic_vector(10 downto 0);
		y     : out std_logic_vector(9 downto 0));
	end component;

	signal hsync : std_logic;
	signal vsync : std_logic;
	signal blank : std_logic;
	signal frame : std_logic;
	signal x_pos : std_logic_vector(10 downto 0);
	signal x_pos_t : std_logic_vector(10 downto 0);
	signal y_pos : std_logic_vector(9 downto 0);

	signal pixel_shift_register : std_logic_vector(C_PI_DATA_WIDTH-1 downto 0);
	signal run_timing : std_logic;

	signal pixels_requested : unsigned(8 downto 0);
	signal pixel_shift_register_content : unsigned(2 downto 0);

	signal wait_for_addr_ack : std_logic;

	signal XIL_NPI_RdFIFO_Pop_int : std_logic;
	signal XIL_NPI_RdFIFO_Pop_int_reg : std_logic;

	-- shadow reg is used to hold the content of the rdFIFO before the pixels are displayed
	-- the thing is that reading from the FIFO can have a latency of up to two clock cycles
	-- to cope with this we first store the pixel data in this register and copy it to pixel shift register
	signal shadow_reg : std_logic_vector(C_PI_DATA_WIDTH-1 downto 0);
	signal shadow_reg_filled : std_logic;

	type reading_fsm_type is (FIFO_REQ_0, FIFO_REQ_1, FIFO_REQ_2);
	signal reading_fsm : reading_fsm_type;

	signal blank_t : std_logic;

	-- how many pixels shall we keep in the FIFO?
	constant PIXEL_REQUEST_LOW : integer := 200;  -- FIFO MAX DEPTH = 512 (BRAM), or 32 (SRL16)
	-- how many pixels shall we request at once?
	constant REQUEST_SIZE : integer := 64; -- allowed values: 16 pixels, 32 pixels (since mpmc3), 64 pixels, 128 pixels

	-- used to detect timeouts from the MPMC2
	signal time_out_counter : unsigned(9 downto 0);

	signal screen_address_offset : unsigned(21 downto 0);
	signal fast_clear_offset : unsigned(21 downto 0);
	signal wait_for_addr_ack_wr : std_logic;
	signal fast_clear_pending : std_logic;
	signal fast_clear_pixels_cleared : unsigned(20 downto 0);

	-- we need to distinguish the x flag for a) fetching data and b) showing data
	-- the _dis flag can only be set during the vsync
	-- while the low_x_resolution_set flag has to be set as soon as we fetch data of the next screen.
	signal low_x_resolution_set : std_logic;
	signal low_x_resolution_set_dis : std_logic;
	signal low_y_resolution_set : std_logic;

	signal pixel_counter_x : unsigned(10 downto 0);
	signal line_displayed_once : std_logic;

	signal heal_the_world : std_logic;

begin

	vga_timing_inst : vga_timing 
	generic map(
		C_NPI_PIXEL_CLK_RATIO => C_NPI_PIXEL_CLK_RATIO
	)
	port map(
		clk => clk,
		rst => rst,
		run => run_timing,
		hsync => hsync,
		vsync => vsync,
		blank => blank,
		frame => frame,
		x_res => x_res,
		x_max => x_max,
		hsync_low  => hsync_low,
		hsync_high => hsync_high,
		y_res => y_res,
		y_max => y_max,
		vsync_low => vsync_low,
		vsync_high => vsync_high,
		x => x_pos,
		y => y_pos
	);

	-- This modules only reads
	XIL_NPI_WrFIFO_Flush <= '0';
	XIL_NPI_WrFIFO_BE    <= (others => '1');
	XIL_NPI_WrFIFO_Data  <= (others => '0');

	-- we request 8/32/64 words, each consisting of 32 bits (i.e. 16/64/128 pixels)
	XIL_NPI_Size <= std_logic_vector(to_unsigned(2, 4)) when REQUEST_SIZE = 16 else
	            std_logic_vector(to_unsigned(3, 4)) when REQUEST_SIZE = 32 else  -- only allowed since mpmc3
	            std_logic_vector(to_unsigned(4, 4)) when REQUEST_SIZE = 64 else
	            std_logic_vector(to_unsigned(5, 4)) when REQUEST_SIZE = 128;

	-- pop from the rdFIFO when the shadow_reg is empty and the rdFIFO is not empty
	XIL_NPI_RdFIFO_Pop <= XIL_NPI_RdFIFO_Pop_int;
	XIL_NPI_RdFIFO_Pop_int  <= '1' when reading_FSM = FIFO_REQ_0 and shadow_reg_filled = '0' and XIL_NPI_RdFIFO_Empty = '0' 
						else '0';

	tft_lcd_hsync <= hsync;
	tft_lcd_vsync <= vsync;

	process(clk, rst) is
		variable pixel_endian_inverse: std_logic_vector(15 downto 0);
	begin
		if rst = '1' then
			tft_lcd_r <= (others => '0');
			tft_lcd_g <= (others => '0');
			tft_lcd_b <= (others => '0');
			tft_lcd_de <= '0';
			pixels_requested <= (others => '0');
			run_timing <= '0';
			x_pos_t <= (others => '0');
			pixel_shift_register_content <= (others => '0');
			pixel_shift_register         <= (others => '0');
			screen_address_offset <= (others => '0');
			XIL_NPI_Addr <= (others => '0');
			XIL_NPI_AddrReq <= '0';
			wait_for_addr_ack <= '0';
			shadow_reg_filled <= '0';
			shadow_reg <= (others => '0');
			reading_fsm <= FIFO_REQ_0;
			blank_t <= '0';
			time_out_counter <= (others => '0');
			XIL_NPI_RdFIFO_Pop_int_reg <= '0';
			XIL_NPI_RdFIFO_Flush <= '0';
			XIL_NPI_RNW <= '0';
			XIL_NPI_WrFIFO_Push  <= '0';

			fast_clear_done <= '1';
			fast_clear_offset <= (others => '0');
			wait_for_addr_ack_wr <= '0';
			fast_clear_pending <= '0';
			fast_clear_pixels_cleared <= (others => '0');
			low_x_resolution_set <= '0';
			low_x_resolution_set_dis <= '0';
			low_y_resolution_set <= '0';

			pixel_counter_x <= (others => '0');
			line_displayed_once <= '0';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -