Border matching seems to be mostly working

This commit is contained in:
jaseg 2021-07-20 19:37:32 +02:00
parent f9c31078d9
commit aeda28a467
5 changed files with 284 additions and 159 deletions

View file

@ -42,7 +42,7 @@
<Option Name="IPUserFilesDir" Val="$PIPUSERFILESDIR"/>
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
<Option Name="EnableBDX" Val="FALSE"/>
<Option Name="WTXSimLaunchSim" Val="560"/>
<Option Name="WTXSimLaunchSim" Val="588"/>
<Option Name="WTModelSimLaunchSim" Val="0"/>
<Option Name="WTQuestaLaunchSim" Val="0"/>
<Option Name="WTIesLaunchSim" Val="0"/>

View file

@ -23,6 +23,8 @@ module window_matcher(
output [11:0] win_h_dbg,
output reg [11:0] win_w,
output reg [11:0] win_h,
output reg [11:0] win_right,
output reg [11:0] win_bottom,
output reg win_locked,
input [7:0] win_red, [7:0] win_green, [7:0] win_blue,
@ -312,6 +314,8 @@ module window_matcher(
win_h <= 0;
win_x <= 0;
win_y <= 0;
win_right <= 0;
win_bottom <= 0;
end else begin
if (in_vsync_reg == 0 && in_vsync == 1) begin
@ -322,11 +326,16 @@ module window_matcher(
win_h <= win_h_int;
win_x <= win_x_int;
win_y <= win_y_int;
win_right <= win_x_int + win_w_int + 1;
win_bottom <= win_y_int + win_h_int + 1;
end else begin
win_w <= 0;
win_h <= 0;
win_x <= 0;
win_y <= 0;
win_right <= 0;
win_bottom <= 0;
end
end
end
@ -334,48 +343,33 @@ module window_matcher(
/* Window H/VSYNC outputs */
reg [11:0] win_blank_ctr;
reg [11:0] win_hsync_ctr;
reg win_hactive;
always @(posedge clk) begin
if (rst) begin
win_blank <= 1;
win_hactive <= 0;
win_blank_ctr <= 0;
win_hsync_ctr <= 0;
end else begin
if (win_locked) begin
/* hsync */
if (scan_x == win_x && win_hactive) begin
win_blank <= 0;
win_blank_ctr <= 1;
end
if (win_blank == 0) begin
win_blank_ctr <= win_blank_ctr + 1;
end
if (win_blank_ctr == win_w || in_blank) begin
if (scan_x == win_right || in_blank) begin
win_blank <= 1;
win_blank_ctr <= 0;
end
if (win_hactive && in_blank_reg && !in_blank) begin
win_hsync_ctr <= win_hsync_ctr + 1;
end
if (scan_y == win_y) begin
win_hactive <= 1;
end
if (win_hsync_ctr == win_h && !in_blank_reg && in_blank) begin
if (scan_y == win_bottom && !in_blank_reg && in_blank) begin
win_hactive <= 0;
end
if (in_vsync_reg == 1 && in_vsync == 0) begin
win_hsync_ctr <= 0;
win_hactive <= 0;
end
end
@ -383,44 +377,34 @@ module window_matcher(
end
/* Border matching */
localparam BORDER_COLOR = 24'h162329,
BACKGROUND_COLOR = 24'hd61ca1,
FONT_FG_COLOR = 24'he1e31b;
localparam BORDER_COLOR = 24'h000000,
BACKGROUND_COLOR = 24'hd020a0,
FONT_FG_COLOR = 24'he0e010;
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;
wire [11:0] border_w = border_right - win_x - 1;
wire [11:0] border_h = border_bottom - win_y;
localparam BSTATE_WAITING = 15'b000000000000001, /* 0001 */
BSTATE_FIRST_LINE = 15'b000000000000010, /* 0002 */
BSTATE_FIRST_LINE_RIGHT = 15'b000000000000100, /* 0004 */
BSTATE_FIRST_LINE_DONE = 15'b000000000001000, /* 0008 */
BSTATE_WIN_LINE_WAIT = 15'b000000000010000, /* 0010 */
BSTATE_WIN_LINE_WIN = 15'b000000000100000, /* 0020 */
BSTATE_WIN_LINE_BUSY = 15'b000000001000000, /* 0040 */
BSTATE_WIN_LINE_DONE = 15'b000000010000000, /* 0080 */
BSTATE_LINE_WAIT = 15'b000000100000000, /* 0100 */
BSTATE_LINE_BUSY = 15'b000001000000000, /* 0200 */
BSTATE_LINE_DONE = 15'b000010000000000, /* 0400 */
BSTATE_DONE = 15'b000100000000000, /* 0800 */
BSTATE_INVALID = 15'b100000000000000; /* 4000 */
reg [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;
if (rst || in_vsync || !win_locked || win_x == 0 || win_y == 0) begin
border_right <= 0;
border_bottom <= 0;
bstate <= BSTATE_WAITING;
@ -428,87 +412,89 @@ module window_matcher(
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;
if (scan_x == win_x && scan_y == win_y) begin
bstate <= BSTATE_FIRST_LINE;
end
end
(BSTATE_FIRST_LINE): begin
if (scan_x == win_right) begin
bstate <= is_bg_px ? BSTATE_FIRST_LINE_RIGHT : BSTATE_INVALID;
end
end
(BSTATE_TOP1): begin
if (!is_border_px) begin
(BSTATE_FIRST_LINE_RIGHT): begin
if (!is_bg_px) begin
bstate <= is_border_px ? BSTATE_FIRST_LINE_DONE : BSTATE_INVALID;
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;
(BSTATE_WIN_LINE_WAIT): begin
if (scan_x == win_x) begin
if (scan_y == win_bottom) begin
bstate <= is_border_px ? BSTATE_LINE_BUSY : BSTATE_INVALID;
end else begin
bstate <= is_border_px ? BSTATE_WIN_LINE_WIN : BSTATE_INVALID;
end
end
end
(BSTATE_TOP2): begin
(BSTATE_WIN_LINE_WIN): begin
if (scan_x == win_right) begin
if (is_border_px) begin
bstate <= BSTATE_DONE;
border_bottom = scan_y;
end else begin
bstate <= is_bg_px ? BSTATE_WIN_LINE_BUSY : BSTATE_INVALID;
end
end
end
(BSTATE_WIN_LINE_BUSY): begin
if (scan_x == border_right) begin
bstate <= BSTATE_TOP2_RIGHT;
bstate <= is_border_px ? BSTATE_WIN_LINE_DONE : BSTATE_INVALID;
end else begin
bstate <= is_border_px ? BSTATE_TOP2 : BSTATE_INVALID;
bstate <= is_bg_px ? BSTATE_WIN_LINE_BUSY : BSTATE_INVALID;
end
end
(BSTATE_MID_LEFT): begin
if (scan_x == border_left) begin
bstate <= is_border_px ? BSTATE_MID_L1 : BSTATE_INVALID;
(BSTATE_LINE_WAIT): begin
if (scan_x == win_x) begin
bstate <= is_border_px ? BSTATE_LINE_BUSY : 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
(BSTATE_LINE_BUSY): begin
if (scan_x == border_right) begin
bstate <= BSTATE_BOT1_RIGHT;
bstate <= is_border_px ? BSTATE_LINE_DONE : BSTATE_INVALID;
end else begin
bstate <= is_border_px ? BSTATE_BOT1 : BSTATE_INVALID;
if (is_border_px) begin
bstate <= BSTATE_DONE;
border_bottom = scan_y;
end else begin
bstate <= is_bg_px ? BSTATE_LINE_BUSY : BSTATE_INVALID;
end
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
(BSTATE_DONE): begin
/* do nothing, reset on next vsync. */
end
(BSTATE_INVALID): begin
/* do nothing, reset on next vsync. */
end
endcase
end else begin /* blank */
end else if (in_blank && !in_blank_reg) 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;
(BSTATE_WAITING ): bstate <= BSTATE_WAITING;
(BSTATE_FIRST_LINE ): bstate <= BSTATE_INVALID;
(BSTATE_FIRST_LINE_RIGHT): bstate <= BSTATE_INVALID;
(BSTATE_FIRST_LINE_DONE ): bstate <= BSTATE_WIN_LINE_WAIT;
(BSTATE_WIN_LINE_WAIT ): bstate <= BSTATE_INVALID;
(BSTATE_WIN_LINE_WIN ): bstate <= BSTATE_INVALID;
(BSTATE_WIN_LINE_BUSY ): bstate <= BSTATE_INVALID;
(BSTATE_WIN_LINE_DONE ): bstate <= BSTATE_WIN_LINE_WAIT;
(BSTATE_LINE_WAIT ): bstate <= BSTATE_INVALID;
(BSTATE_LINE_BUSY ): bstate <= BSTATE_INVALID;
(BSTATE_LINE_DONE ): bstate <= BSTATE_LINE_WAIT;
(BSTATE_DONE ): bstate <= BSTATE_DONE;
(BSTATE_INVALID ): bstate <= BSTATE_INVALID;
endcase
end
end

View file

View file

@ -60,6 +60,7 @@ module window_matcher_tb();
end
`include "test_data/00WM_TEST_POS_LOADERS.v"
`include "test_data/00WM_TEST_BORDER_LOADERS.v"
integer read_pos;
reg [23:0] expected_data;
@ -69,7 +70,8 @@ module window_matcher_tb();
reg win_blank_exp_last, win_header_last;
reg in_vsync_last;
initial begin
`include "test_data/00WM_TEST_POS_RUNNERS.v"
//`include "test_data/00WM_TEST_POS_RUNNERS.v"
`include "test_data/00WM_TEST_BORDER_RUNNERS.v"
$finish;
end

File diff suppressed because one or more lines are too long