📄 npi_vga.vhd
字号:
-- 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 + -