terminal/framebuffer.vhd

103 lines
2.8 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use std.textio.all;
use ieee.std_logic_textio.all;
entity framebuffer is
generic (
input_clk: integer
);
port (
clk: in std_logic;
x: in std_logic_vector(9 downto 0);
y: in std_logic_vector(8 downto 0);
rgb: out std_logic_vector(23 downto 0);
write_enable: std_logic;
write_address: std_logic_vector(12 downto 0);
write_data: std_logic_vector(7 downto 0)
);
end framebuffer;
architecture logic of framebuffer is
type rom_type is array(0 to 127) of std_logic_vector(63 downto 0);
impure function read_font(filename: in string) return rom_type is
file rom_file: text is in filename;
variable rom_line: line;
variable rom: rom_type;
begin
-- skip comment in first line
readline(rom_file, rom_line);
for i in rom_type'range loop
readline(rom_file, rom_line);
hread(rom_line, rom(i));
end loop;
return rom;
end function;
constant font: rom_type := read_font("font.hex");
signal read_address: std_logic_vector(12 downto 0);
signal current_char: std_logic_vector(7 downto 0);
signal current_glyph: std_logic_vector(63 downto 0);
-- delay by 2 cycles to match the delay of x/y -> rgb
constant glyph_pos_length: integer := 2;
type glyph_pos_type is array(1 to glyph_pos_length) of integer range 0 to 63;
signal glyph_pos: glyph_pos_type;
begin
read_address <= x(9 downto 3) & y(8 downto 3);
terminal_buffer: entity work.ram_2port generic map (
WIDTH_BITS => 8,
DEPTH_BITS => 13
) port map (
clk => clk,
ra => read_address,
do => current_char,
we => write_enable,
wa => write_address,
di => write_data
);
process(clk)
variable current_glyph_pos: integer range 0 to 127;
begin
if rising_edge(clk) then
current_glyph_pos := to_integer(unsigned(current_char));
current_glyph <= font(current_glyph_pos);
end if;
end process;
delay_glyph_pos:
process(clk)
variable combined: std_logic_vector(5 downto 0);
begin
if rising_edge(clk) then
combined := y(2 downto 0) & x(2 downto 0);
glyph_pos(glyph_pos_length) <= to_integer(unsigned(combined));
-- move all elements one index down
for i in 1 to glyph_pos_length - 1 loop
glyph_pos(i) <= glyph_pos(i + 1);
end loop;
end if;
end process delay_glyph_pos;
-- actually currently BRG
rgb <=
"111111111111111111111111" when current_glyph(glyph_pos(1)) = '1' else
"000000000000000000000000";
end logic;