`timescale 1ns / 1ps module term_renderer( input rst, clk, input in_blank, in_vsync, in_hsync, input [19:0] glyphmem_data, output [15:0] glyphmem_r_addr, output out_hsync, out_vsync, output [7:0] out_red, output [7:0] out_green, output [7:0] out_blue ); parameter GLYPHMEM_W = 256; /* glyphs */ parameter GLYPHMEM_H = 128; /* glyphs */ /* Glyph table instantiation */ `include "gen/gen_font_params_default.vh" localparam FONT_GLYPH_W = `GEN_FONT_GLYPH_W_default; localparam FONT_GLYPH_H = `GEN_FONT_GLYPH_H_default; localparam FONT_GLYPH_COUNT = `GEN_FONT_GLYPH_COUNT_default; reg [FONT_GLYPH_W-1:0] glyph_table_default [0:FONT_GLYPH_COUNT*FONT_GLYPH_H-1]; /* This is the dumbest thing, but it seems vivado is just *that* stupid. */ `ifdef SYNTHESIS initial $readmemh("../../src/gen/gen_glyphtable_default.hex", glyph_table_default); `else initial $readmemh("../../../../src/gen/gen_glyphtable_default.hex", glyph_table_default); `endif `include "gen/gen_font_params_bold.vh" /* NOTE: Bold font must have same glyph w/h, glyph count as regular font above */ reg [FONT_GLYPH_W-1:0] glyph_table_bold [0:FONT_GLYPH_COUNT*FONT_GLYPH_H-1]; `ifdef SYNTHESIS initial $readmemh("../../src/gen/gen_glyphtable_bold.hex", glyph_table_bold); `else initial $readmemh("../../../../src/gen/gen_glyphtable_bold.hex", glyph_table_bold); `endif /* Color palette */ function [23:0] color_palette; input [3:0] index; begin /* Peppermint color palette: https://noahfrederick.com/log/lion-terminal-theme-peppermint */ case (index) default: color_palette = 24'h353535; (1): color_palette = 24'he64569; (2): color_palette = 24'h89d287; (3): color_palette = 24'hdab752; (4): color_palette = 24'h439ecf; (5): color_palette = 24'hd961dc; (6): color_palette = 24'h64aaaf; (7): color_palette = 24'hb3b3b3; (8): color_palette = 24'h535353; (9): color_palette = 24'he4859a; (10): color_palette = 24'ha2cca1; (11): color_palette = 24'he1e387; (12): color_palette = 24'h6fbbe2; (13): color_palette = 24'he586e7; (14): color_palette = 24'h96dcda; (15): color_palette = 24'hdedede; endcase end endfunction /* Glyph x/y synchronization logic */ reg [11:0] glyph_x; reg [11:0] glyph_y; reg [FONT_GLYPH_W-1:0] glyph_sreg_out; reg [5:0] px_x; reg [5:0] px_y; reg in_hsync_last, in_vsync_last; wire [7:0] gm_data_glyph = glyphmem_data[7:0]; wire [11:0] gm_data_style = glyphmem_data[19:8]; reg [11:0] glyphmem_style_reg; wire [3:0] gm_data_fgcolor = glyphmem_style_reg[3:0]; wire [3:0] gm_data_bgcolor = glyphmem_style_reg[7:4]; wire gm_data_bold = gm_data_style[10]; wire gm_data_underline = glyphmem_style_reg[11] && !newline_found; reg newline_found; assign out_vsync = in_vsync_last; assign out_hsync = in_hsync_last; assign glyphmem_r_addr = (GLYPHMEM_W*glyph_y) + glyph_x; wire px_data = glyph_sreg_out[FONT_GLYPH_W-1] || (gm_data_underline && px_y == FONT_GLYPH_H-2); assign {out_red, out_green, out_blue} = color_palette(px_data ? gm_data_fgcolor : gm_data_bgcolor); /* Core logic */ always @(posedge clk) begin if (rst) begin glyph_x <= 0; glyph_y <= 0; px_x <= 0; px_y <= 0; in_hsync_last <= 0; in_vsync_last <= 0; glyph_sreg_out <= 0; glyphmem_style_reg <= 0; newline_found <= 0; end else begin in_hsync_last <= in_hsync; in_vsync_last <= in_vsync; if (in_hsync_last && !in_hsync) begin glyph_x <= 0; px_x <= 0; newline_found <= 0; if (px_y != FONT_GLYPH_H-1) begin px_y <= px_y + 1; end else begin glyph_y <= glyph_y + 1; px_y <= 0; end end else if (!in_blank) begin if (px_x != FONT_GLYPH_W-1) begin px_x <= px_x + 1; end else begin px_x <= 0; end if (px_x == 0) begin if (newline_found) begin glyph_sreg_out <= 0; end else if (gm_data_bold) begin glyph_sreg_out <= glyph_table_bold[gm_data_glyph*FONT_GLYPH_H + px_y]; end else begin glyph_sreg_out <= glyph_table_default[gm_data_glyph*FONT_GLYPH_H + px_y]; end glyphmem_style_reg <= gm_data_style; glyph_x <= glyph_x + 1; if (gm_data_glyph == 8'h0a) begin /* Newline character */ newline_found <= 1; end end else begin glyph_sreg_out <= {glyph_sreg_out[FONT_GLYPH_W-2:0], 1'b0}; end end else if (!in_hsync_last) begin glyph_sreg_out <= 0; glyphmem_style_reg <= 0; end if (in_vsync_last && !in_vsync) begin glyph_y <= 0; px_y <= 0; end end end endmodule