2022-04-07 18:46:57 +02:00

157 lines
4.5 KiB
VHDL

-- altera vhdl_input_version vhdl_2008
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity PixTrans is
generic (
MAX_H : natural;
MAX_W : natural
);
port (
clk : in std_logic;
rst_n : in std_logic;
lcd_req : in std_logic;
data : out std_logic_vector(15 downto 0);
empty : out std_logic;
fifo_req : out std_logic;
fifo_q : in std_logic_vector(31 downto 0);
fifo_empty : in std_logic;
-- Currently configured width/height of the buffer
w : in natural;
h : in natural
);
end PixTrans;
architecture behavioral of PixTrans is
subtype Pixel is std_logic_vector(15 downto 0);
-- Generic constants
constant BLANK : Pixel := "0000000000000000"; --(others => '0');
-- Type definitions
type PIXEL_SOURCE is (S_BLANK, S_FIFO, S_BUFFER);
-- Inferred registers
signal pixbuf_reg, pixbuf_next : Pixel;
signal pixbufvalid_reg, pixbufvalid_next : boolean;
signal pos_x_reg, pos_x_next : integer range 1 to MAX_W;
signal pos_y_reg, pos_y_next : integer range 1 to MAX_H;
signal pix_src_reg, pix_src_next : PIXEL_SOURCE;
signal finished_next, finished_reg : std_logic;
-- Convenience signals
signal inBlankArea_reg, inBlankArea_next : boolean;
signal lcd_req_delayed_reg : std_logic;
begin
-- Update cursor
process(all) begin
finished_next <= finished_reg;
pos_y_next <= pos_y_reg;
pos_x_next <= pos_x_reg;
if lcd_req_delayed_reg = '1' then
if pos_x_reg = MAX_W and pos_y_reg = MAX_H then
pos_x_next <= 1;
pos_y_next <= 1;
elsif pos_x_reg = MAX_W then
pos_x_next <= 1;
pos_y_next <= pos_y_reg + 1;
else
pos_x_next <= pos_x_reg + 1;
end if;
if pos_x_reg = MAX_W and pos_y_reg = MAX_H then
finished_next <= '1' and not finished_reg;
else
finished_next <= '0';
end if;
end if;
inBlankArea_next <= pos_y_next > h or pos_x_next > w;
end process;
-- Data process
process(all) begin
pix_src_next <= pix_src_reg;
pixbufvalid_next <= pixbufvalid_reg;
-- FIFO output signals
fifo_req <= '0';
if lcd_req_delayed_reg = '1' then
if inBlankArea_next then
pix_src_next <= S_BLANK;
elsif pixbufvalid_reg then
-- Has valid pixel in pixel buffer
pix_src_next <= S_BUFFER;
pixbufvalid_next <= false;
else
fifo_req <= '1';
-- fifo_req should be kept high until pixel is available
if fifo_empty = '0' then
-- Must request pixel from FIFO
pix_src_next <= S_FIFO;
pixbufvalid_next <= true;
end if;
end if;
end if;
end process;
-- Data request multiplexer (pixel source)
with pix_src_reg select data <=
BLANK when S_BLANK,
fifo_q(15 downto 0) when S_FIFO,
pixbuf_reg when S_BUFFER;
-- Fill pixel buffer with the upper half word of the input FIFO word when
-- reading from the fifo
pixbuf_next <= fifo_q(31 downto 16) when pix_src_reg = S_FIFO else pixbuf_reg;
-- LCD Controller empty signal
process(all) begin
if fifo_empty = '1' then
empty <= '1';
else
empty <= finished_reg;
end if;
end process;
-- Clocking process/register inferrence
process(clk) begin
if rising_edge(clk) then
if rst_n = '0' then
pos_x_reg <= 1;
pos_y_reg <= 1;
pixbuf_reg <= BLANK;
pixbufvalid_reg <= false;
pix_src_reg <= S_BLANK;
inBlankArea_reg <= false;
finished_reg <= '0';
lcd_req_delayed_reg <= '0';
else
pos_x_reg <= pos_x_next;
pos_y_reg <= pos_y_next;
pixbuf_reg <= pixbuf_next;
pixbufvalid_reg <= pixbufvalid_next;
pix_src_reg <= pix_src_next;
inBlankArea_reg <= inBlankArea_next;
finished_reg <= finished_next;
lcd_req_delayed_reg <= lcd_req;
end if;
end if;
end process;
end behavioral ; -- behavioral