From f9c31078d9106d094185181089cbd69f37d1b9d0 Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 20 Jul 2021 15:59:50 +0200 Subject: [PATCH] WIP --- demo/fpga/src/window_matcher.v | 152 ++++++++++++++++++++++++++---- demo/fw/tools/create_age_email.py | 11 ++- 2 files changed, 140 insertions(+), 23 deletions(-) diff --git a/demo/fpga/src/window_matcher.v b/demo/fpga/src/window_matcher.v index 4bb542b..578e756 100644 --- a/demo/fpga/src/window_matcher.v +++ b/demo/fpga/src/window_matcher.v @@ -1,24 +1,4 @@ `timescale 1ns / 1ps -////////////////////////////////////////////////////////////////////////////////// -// Company: -// Engineer: -// -// Create Date: 06/14/2021 05:44:00 PM -// Design Name: -// Module Name: window_matcher -// Project Name: -// Target Devices: -// Tool Versions: -// Description: -// -// Dependencies: -// -// Revision: -// Revision 0.01 - File Created -// Additional Comments: -// -////////////////////////////////////////////////////////////////////////////////// - module window_matcher( /* Pixel clock and synchronous, active-high reset */ @@ -56,6 +36,7 @@ module window_matcher( output [11:0] scan_y_dbg ); + /* Pixel data pipeline */ wire [23:0] in_pxd = {in_red, in_green, in_blue}; wire [23:0] win_pxd = {win_red, win_green, win_blue}; wire [23:0] out_pxd; @@ -400,6 +381,137 @@ module window_matcher( end end end + + /* Border matching */ + localparam BORDER_COLOR = 24'h162329, + BACKGROUND_COLOR = 24'hd61ca1, + FONT_FG_COLOR = 24'he1e31b; + wire is_border_px = (in_pxd_unfucked & 24'hf0f0f0) == (BORDER_COLOR & 24'hf0f0f0); + wire is_bg_px = (in_pxd_unfucked & 24'hf0f0f0) == (BACKGROUND_COLOR & 24'hf0f0f0) || + (in_pxd_unfucked & 24'hf0f0f0) == (FONT_FG_COLOR & 24'hf0f0f0); + reg [11:0] border_right; + reg [11:0] border_bottom; + reg row_valid_border_h, row_valid_border_v; + reg valid_border; + wire [11:0] border_top = win_y - 2; + wire [11:0] border_left = win_x - 2; + localparam BSTATE_WAITING = 15'b000000000000001, + BSTATE_TOP1 = 15'b000000000000010, + BSTATE_TOP1_RIGHT = 15'b000000000000100, + BSTATE_TOP2_LEFT = 15'b000000000001000, + BSTATE_TOP2 = 15'b000000000010000, + BSTATE_TOP2_RIGHT = 15'b000000000100000, + BSTATE_MID_LEFT = 15'b000000001000000, + BSTATE_MID_L1 = 15'b000000010000000, + BSTATE_MID_L2 = 15'b000000010000000, + BSTATE_MID_CENTER = 15'b000000010000000, + BSTATE_MID_R1 = 15'b000000010000000, + BSTATE_MID_R2 = 15'b000000010000000, + BSTATE_MID_RIGHT = 15'b000000100000000, + BSTATE_BOT1_LEFT = 15'b000001000000000, + BSTATE_BOT1 = 15'b000010000000000, + BSTATE_BOT1_RIGHT = 15'b000100000000000, + BSTATE_BOT2 = 15'b001000000000000, + BSTATE_FINISHED = 15'b010000000000000; + BSTATE_INVALID = 15'b100000000000000; + wire [14:0] bstate; + + always @(posedge clk) begin + if (rst || in_vsync || !win_locked || win_x < 2 || win_y < 2) begin + row_valid_border_h <= 0; + row_valid_border_v <= 0; + valid_border <= 0; + border_right <= 0; + border_bottom <= 0; + bstate <= BSTATE_WAITING; + + end else if (!in_blank) begin + case (bstate) + (BSTATE_WAITING): begin + if (scan_x == border_left && scan_y == border_top) begin /* top left pixel of border */ + bstate <= is_border_px ? BSTATE_TOP1 : BSTATE_INVALID; + end + end + (BSTATE_TOP1): begin + if (!is_border_px) begin + border_right <= scan_x; + bstate <= BSTATE_TOP1_RIGHT; + end + end + (BSTATE_TOP2_LEFT): begin + if (scan_x == border_left) begin + bstate <= is_border_px ? BSTATE_TOP2 : BSTATE_INVALID; + end + end + (BSTATE_TOP2): begin + if (scan_x == border_right) begin + bstate <= BSTATE_TOP2_RIGHT; + end else begin + bstate <= is_border_px ? BSTATE_TOP2 : BSTATE_INVALID; + end + end + (BSTATE_MID_LEFT): begin + if (scan_x == border_left) begin + bstate <= is_border_px ? BSTATE_MID_L1 : BSTATE_INVALID; + end + end + (BSTATE_MID_L1): begin + bstate <= is_border_px ? BSTATE_MID_L2 : BSTATE_INVALID; + end + (BSTATE_MID_L2): begin + if (is_border_px) begin + bstate <= BSTATE_BOT1; + end else if (is_bg_px) begin + bstate <= BSTATE_MID_C; + end else begin + bstate <= BSTATE_INVALID; + end + end + (BSTATE_MID_C): begin + if (is_border_px) begin + bstate <= BSTATE_MID_R1; + end else if (is_bg_px) begin + bstate <= BSTATE_MID_C; + end else begin + bstate <= BSTATE_INVALID; + end + end + (BSTATE_MID_R1): begin + bstate <= is_border_px ? BSTATE_MID_R2 : BSTATE_INVALID; + end + (BSTATE_MID_R2): begin + bstate <= (scan_x == border_right) ? BSTATE_MID_RIGHT : BSTATE_INVALID; + end + (BSTATE_BOT1): begin + if (scan_x == border_right) begin + bstate <= BSTATE_BOT1_RIGHT; + end else begin + bstate <= is_border_px ? BSTATE_BOT1 : BSTATE_INVALID; + end + end + (BSTATE_BOT2): begin + if (scan_x == border_right) begin + bstate <= BSTATE_BOT1_RIGHT; + end else begin + bstate <= is_border_px ? BSTATE_BOT1 : BSTATE_INVALID; + end + end + (BSTATE_FINISHED): begin + end + (BSTATE_INVALID): begin + /* do nothing, reset on next vsync. */ + end + endcase + + end else begin /* blank */ + case (bstate) + (BSTATE_TOP1_RIGHT): bstate <= BSTATE_TOP2_LEFT; + (BSTATE_TOP2_RIGHT): bstate <= BSTATE_MID_LEFT; + (BSTATE_MID_RIGHT): bstate <= BSTATE_MID_LEFT; + (BSTATE_BOT1_RIGHT): bstate <= BSTATE_BOT2_LEFT; + endcase + end + end /* Payload extractor */ reg [23:0] in_pxd_last; diff --git a/demo/fw/tools/create_age_email.py b/demo/fw/tools/create_age_email.py index 7f448da..4a5077b 100644 --- a/demo/fw/tools/create_age_email.py +++ b/demo/fw/tools/create_age_email.py @@ -27,10 +27,15 @@ def age_encrypt(content, keys): input=content.encode('utf-8')) return proc.stdout +BORDER_COLOR = '#000000' +BACKGROUND_COLOR = '#d61ca1' +FONT_FG_COLOR = '#e1e31b' def pack_html(payload_img_cid, hint_img_cid): + return textwrap.dedent(f'''\ - - + +
@@ -38,7 +43,7 @@ def pack_html(payload_img_cid, hint_img_cid): ''').strip() -def create_hint_img(text, max_w=200, fgcolor='#e1e31b', bgcolor='#d61ca1'): +def create_hint_img(text, max_w=200, fgcolor=FONT_FG_COLOR, bgcolor=BACKGROUND_COLOR): relative_path = (Path(__file__).parent / '../../../upstream/terminus-font-4.49.1/ter-u16b.bdf').resolve() font_file = os.getenv('HINT_FONT', str(relative_path)) font = bdfparser.Font(font_file)