diff --git a/Artix-7-HDMI-processing.xpr b/Artix-7-HDMI-processing.xpr
index 55a2084..c2d8944 100644
--- a/Artix-7-HDMI-processing.xpr
+++ b/Artix-7-HDMI-processing.xpr
@@ -49,13 +49,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -411,7 +411,6 @@
-
diff --git a/src/top.v b/src/top.v
index 2ceebbd..29b5563 100644
--- a/src/top.v
+++ b/src/top.v
@@ -317,6 +317,9 @@ wire [11:0] win_x_dbg;
wire [11:0] win_y_dbg;
wire [11:0] win_w_dbg;
wire [11:0] win_h_dbg;
+wire [11:0] scan_x_dbg;
+wire [11:0] scan_y_dbg;
+wire [8:0] match_dbg;
window_matcher window_matcher_i (
.clk(clk),
@@ -324,6 +327,9 @@ window_matcher window_matcher_i (
.bypass(bypass),
.debug(matcher_debug),
+ .scan_x_dbg(scan_x_dbg),
+ .scan_y_dbg(scan_y_dbg),
+ .match_dbg(match_dbg),
.in_blank(in_blank),
.in_hsync(in_hsync),
@@ -358,27 +364,25 @@ window_matcher window_matcher_i (
.out_blue(out_blue)
);
-/*
ila_0 i_ila_0 (
.clk(clk),
.probe0(win_x_dbg),
.probe1(win_y_dbg),
- .probe2(win_w_dbg),
- .probe3(win_h_dbg),
+ .probe2(scan_x_dbg),
+ .probe3(scan_y_dbg),
.probe4({in_red, in_green, in_blue}),
.probe5(in_blank),
.probe6(in_hsync),
.probe7(in_vsync),
- .probe8(1'b0),
+ .probe8(match_dbg),
.probe9(1'b0),
- .probe10(win_blank),
- .probe11(win_locked),
- .probe12(out_data_en),
- .probe13(out_data_valid),
- .probe14(out_hsync),
- .probe15(out_vsync)
+ .probe10(1'b0),
+ .probe11(1'b0),
+ .probe12(win_blank),
+ .probe13(win_locked),
+ .probe14(out_data_en),
+ .probe15(out_data_valid)
);
-*/
endmodule
\ No newline at end of file
diff --git a/src/window_matcher.v b/src/window_matcher.v
index e3b6530..46a471e 100644
--- a/src/window_matcher.v
+++ b/src/window_matcher.v
@@ -51,7 +51,10 @@ module window_matcher(
output reg out_data_valid,
output [23:0] out_data,
- output [7:0] debug
+ output [7:0] debug,
+ output [7:0] match_dbg,
+ output [11:0] scan_x_dbg,
+ output [11:0] scan_y_dbg
);
wire [23:0] in_pxd = {in_red, in_green, in_blue};
@@ -59,20 +62,49 @@ module window_matcher(
wire [23:0] out_pxd;
assign {out_red, out_green, out_blue} = out_pxd;
- assign debug = {in_pxd_match_dbg, win_blank, win_hactive, 2'b00};
+ assign debug = {in_pxd_match_dbg, win_blank, win_hactive, win_locked, 1'b0};
/* Pattern matching */
- localparam [23:0] MARKER_0 = 24'h012345;
- localparam [23:0] MARKER_1 = 24'h6789ab;
- localparam [23:0] MARKER_2 = 24'hcdef42;
- localparam [23:0] MARKER_3 = 24'h543210;
+ localparam [23:0] MARKER_0 = 24'h001020;
+ localparam [23:0] MARKER_1 = 24'h304050;
+ localparam [23:0] MARKER_2 = 24'h607080;
+ localparam [23:0] MARKER_3 = 24'h90a0b0;
+ localparam [23:0] MARKER_4 = 24'hc0d0e0;
+ localparam [23:0] MARKER_5 = 24'hf04020;
+ localparam [23:0] MARKER_6 = 24'h504030;
+ localparam [23:0] MARKER_7 = 24'h201000;
- wire [3:0] in_pxd_match = {
- in_pxd == MARKER_3,
- in_pxd == MARKER_2,
- in_pxd == MARKER_1,
- in_pxd == MARKER_0
+ /* In captures, we rarely observe that a channel value like 8'h50 gets changed to 8'h4f. I have no idea why this is, and pröperly debugging it is a major To-Do. For now, however, we simply dump the four LSBs and adjust the upper nibble to round.
+ */
+ function [7:0] unfuck;
+ input [7:0] in_ch;
+ begin
+ unfuck[3:0] = 4'h0;
+
+ if (in_ch[3:0] < 8) begin
+ unfuck[7:4] = in_ch[7:4];
+ end else begin
+ unfuck[7:4] = in_ch[7:4] + 1;
+ end
+ end
+ endfunction
+
+ wire [7:0] in_red_unfucked = unfuck(in_red);
+ wire [7:0] in_green_unfucked = unfuck(in_green);
+ wire [7:0] in_blue_unfucked = unfuck(in_blue);
+ wire [23:0] in_pxd_unfucked = {in_red_unfucked, in_green_unfucked, in_blue_unfucked};
+
+ wire [7:0] in_pxd_match = {
+ in_pxd_unfucked == MARKER_7,
+ in_pxd_unfucked == MARKER_6,
+ in_pxd_unfucked == MARKER_5,
+ in_pxd_unfucked == MARKER_4,
+ in_pxd_unfucked == MARKER_3,
+ in_pxd_unfucked == MARKER_2,
+ in_pxd_unfucked == MARKER_1,
+ in_pxd_unfucked == MARKER_0
};
+ assign match_dbg = in_pxd_match;
reg [3:0] in_pxd_match_dbg;
always @(posedge clk) begin
@@ -80,19 +112,23 @@ module window_matcher(
in_pxd_match_dbg <= 0;
end else begin
if (!in_blank) begin
- in_pxd_match_dbg <= in_pxd_match_dbg | in_pxd_match;
+ in_pxd_match_dbg <= in_pxd_match_dbg | in_pxd_match[7:4];
end else begin
in_pxd_match_dbg <= 0;
end
end
end
- reg [3:0] in_pxd_match_sr [2:0];
+ reg [7:0] in_pxd_match_sr [6:0];
wire in_pxd_pattern_match =
- in_pxd_match[3] == 1
- && in_pxd_match_sr[2][0] == 1
- && in_pxd_match_sr[1][1] == 1
- && in_pxd_match_sr[0][2] == 1
+ in_pxd_match_sr[6][0]
+ && in_pxd_match_sr[5][1]
+ && in_pxd_match_sr[4][2]
+ && in_pxd_match_sr[3][3]
+ && in_pxd_match_sr[2][4]
+ && in_pxd_match_sr[1][5]
+ && in_pxd_match_sr[0][6]
+ && in_pxd_match[7]
&& !in_blank;
always @(posedge clk) begin
@@ -100,18 +136,28 @@ module window_matcher(
in_pxd_match_sr[0] <= 0;
in_pxd_match_sr[1] <= 0;
in_pxd_match_sr[2] <= 0;
+ in_pxd_match_sr[3] <= 0;
+ in_pxd_match_sr[4] <= 0;
+ in_pxd_match_sr[5] <= 0;
+ in_pxd_match_sr[6] <= 0;
end else begin
in_pxd_match_sr[0] <= in_pxd_match;
in_pxd_match_sr[1] <= in_pxd_match_sr[0];
in_pxd_match_sr[2] <= in_pxd_match_sr[1];
+ in_pxd_match_sr[3] <= in_pxd_match_sr[2];
+ in_pxd_match_sr[4] <= in_pxd_match_sr[3];
+ in_pxd_match_sr[5] <= in_pxd_match_sr[4];
+ in_pxd_match_sr[6] <= in_pxd_match_sr[5];
end
end
/* Pixel scan state machine */
reg [11:0] scan_x;
reg [11:0] scan_y;
+ assign scan_x_dbg = scan_x;
+ assign scan_y_dbg = scan_y;
- reg [11:0] scan_x_reg [3:0];
+ reg [11:0] scan_x_reg [7:0];
reg in_hsync_reg;
reg in_vsync_reg;
reg in_blank_reg;
@@ -128,6 +174,10 @@ module window_matcher(
scan_x_reg[1] <= 0;
scan_x_reg[2] <= 0;
scan_x_reg[3] <= 0;
+ scan_x_reg[4] <= 0;
+ scan_x_reg[5] <= 0;
+ scan_x_reg[6] <= 0;
+ scan_x_reg[7] <= 0;
scan_y <= 0;
in_hsync_reg <= 0;
in_vsync_reg <= 0;
@@ -143,6 +193,10 @@ module window_matcher(
scan_x_reg[1] <= scan_x_reg[0];
scan_x_reg[2] <= scan_x_reg[1];
scan_x_reg[3] <= scan_x_reg[2];
+ scan_x_reg[4] <= scan_x_reg[3];
+ scan_x_reg[5] <= scan_x_reg[4];
+ scan_x_reg[6] <= scan_x_reg[5];
+ scan_x_reg[7] <= scan_x_reg[6];
if (!in_blank) begin
scan_x <= scan_x + 1;
@@ -154,6 +208,10 @@ module window_matcher(
scan_x_reg[1] <= 0;
scan_x_reg[2] <= 0;
scan_x_reg[3] <= 0;
+ scan_x_reg[4] <= 0;
+ scan_x_reg[5] <= 0;
+ scan_x_reg[6] <= 0;
+ scan_x_reg[7] <= 0;
scan_x <= 0;
end
@@ -213,7 +271,7 @@ module window_matcher(
ST_MAT_WAITING: begin
if (in_pxd_pattern_match) begin
matcher_state <= ST_MAT_RX0;
- win_x_int <= scan_x_reg[3];
+ win_x_int <= scan_x_reg[7];
win_y_int <= scan_y;
end
end
diff --git a/test_bench/window_matcher_tb_gen.ipynb b/test_bench/window_matcher_tb_gen.ipynb
index e658e88..951d741 100644
--- a/test_bench/window_matcher_tb_gen.ipynb
+++ b/test_bench/window_matcher_tb_gen.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "markdown",
- "id": "italian-singapore",
+ "id": "sublime-leave",
"metadata": {},
"source": [
"# Window Matcher Testcase Generator"
@@ -11,7 +11,7 @@
{
"cell_type": "code",
"execution_count": 1,
- "id": "compact-saskatchewan",
+ "id": "unauthorized-boston",
"metadata": {},
"outputs": [],
"source": [
@@ -32,8 +32,8 @@
},
{
"cell_type": "code",
- "execution_count": 33,
- "id": "adequate-invalid",
+ "execution_count": 45,
+ "id": "strong-motivation",
"metadata": {},
"outputs": [],
"source": [
@@ -51,7 +51,17 @@
" BLUE = 2\n",
" ALPHA = 3\n",
" \n",
- "WINDOW_MAGIC = np.array([[0x01, 0x23, 0x45], [0x67, 0x89, 0xab], [0xcd, 0xef, 0x42], [0x54, 0x32, 0x10]])\n",
+ "#WINDOW_MAGIC = np.array([[0x01, 0x23, 0x45], [0x67, 0x89, 0xab], [0xcd, 0xef, 0x42], [0x54, 0x32, 0x10]])\n",
+ "WINDOW_MAGIC = np.array([\n",
+ " (0x00, 0x10, 0x20),\n",
+ " (0x30, 0x40, 0x50),\n",
+ " (0x60, 0x70, 0x80),\n",
+ " (0x90, 0xa0, 0xb0),\n",
+ " (0xc0, 0xd0, 0xe0),\n",
+ " (0xf0, 0x40, 0x20),\n",
+ " (0x50, 0x40, 0x30),\n",
+ " (0x20, 0x10, 0x00),\n",
+ "])\n",
" \n",
"\n",
"def add_alpha(fb):\n",
@@ -90,12 +100,12 @@
" def encode_val(val):\n",
" return np.array([(val//65536)&0xff, (val%65536//256)&0xff, (val%256)&0xff]).astype(int)\n",
" \n",
- " win_data[0, :4, :3] = WINDOW_MAGIC\n",
- " win_data[0, 4, :3] = encode_val(win_x)\n",
- " win_data[0, 5, :3] = encode_val(win_y)\n",
- " win_data[0, 6, :3] = encode_val(win_w)\n",
- " win_data[0, 7, :3] = encode_val(win_h)\n",
- " win_data[0, :8, 3] |= AlphaFlags.WIN_HEADER.value;\n",
+ " win_data[0, :8, :3] = WINDOW_MAGIC\n",
+ " win_data[0, 8, :3] = encode_val(win_x)\n",
+ " win_data[0, 9, :3] = encode_val(win_y)\n",
+ " win_data[0, 10, :3] = encode_val(win_w)\n",
+ " win_data[0, 11, :3] = encode_val(win_h)\n",
+ " win_data[0, :12, 3] |= AlphaFlags.WIN_HEADER.value;\n",
" \n",
" win_h, win_w, _ = win_data.shape\n",
" h, w, _ = fb.shape\n",
@@ -122,8 +132,8 @@
},
{
"cell_type": "code",
- "execution_count": 34,
- "id": "atomic-stanley",
+ "execution_count": 46,
+ "id": "interested-silence",
"metadata": {},
"outputs": [],
"source": [
@@ -133,7 +143,7 @@
{
"cell_type": "code",
"execution_count": 36,
- "id": "integrated-wright",
+ "id": "professional-register",
"metadata": {},
"outputs": [],
"source": [
@@ -143,7 +153,7 @@
{
"cell_type": "code",
"execution_count": 37,
- "id": "welsh-purse",
+ "id": "soviet-peter",
"metadata": {},
"outputs": [],
"source": [
@@ -167,7 +177,7 @@
{
"cell_type": "code",
"execution_count": 38,
- "id": "optical-villa",
+ "id": "selective-fundamental",
"metadata": {},
"outputs": [
{
@@ -237,7 +247,7 @@
{
"cell_type": "code",
"execution_count": 39,
- "id": "preceding-tyler",
+ "id": "executive-technique",
"metadata": {},
"outputs": [],
"source": [
@@ -259,7 +269,7 @@
{
"cell_type": "code",
"execution_count": 42,
- "id": "russian-lawrence",
+ "id": "satisfied-buying",
"metadata": {},
"outputs": [
{
@@ -393,7 +403,7 @@
{
"cell_type": "code",
"execution_count": 8,
- "id": "conditional-louisiana",
+ "id": "controlling-stanley",
"metadata": {},
"outputs": [],
"source": [
@@ -405,7 +415,7 @@
{
"cell_type": "code",
"execution_count": 27,
- "id": "serial-baghdad",
+ "id": "brave-labor",
"metadata": {},
"outputs": [
{
@@ -428,7 +438,7 @@
{
"cell_type": "code",
"execution_count": 28,
- "id": "graduate-chuck",
+ "id": "informal-marketplace",
"metadata": {},
"outputs": [
{
@@ -451,7 +461,7 @@
{
"cell_type": "code",
"execution_count": 26,
- "id": "chronic-geography",
+ "id": "desperate-valentine",
"metadata": {},
"outputs": [
{
@@ -472,7 +482,7 @@
{
"cell_type": "code",
"execution_count": 10,
- "id": "returning-validation",
+ "id": "whole-induction",
"metadata": {},
"outputs": [
{
@@ -495,7 +505,7 @@
{
"cell_type": "code",
"execution_count": 36,
- "id": "superior-shareware",
+ "id": "understood-french",
"metadata": {},
"outputs": [
{
@@ -518,7 +528,7 @@
{
"cell_type": "code",
"execution_count": 41,
- "id": "racial-restoration",
+ "id": "usual-chair",
"metadata": {},
"outputs": [
{
@@ -539,7 +549,7 @@
{
"cell_type": "code",
"execution_count": 11,
- "id": "efficient-gasoline",
+ "id": "smoking-waters",
"metadata": {},
"outputs": [
{
@@ -562,7 +572,7 @@
{
"cell_type": "code",
"execution_count": 12,
- "id": "preceding-coating",
+ "id": "filled-technique",
"metadata": {},
"outputs": [
{
@@ -600,7 +610,7 @@
{
"cell_type": "code",
"execution_count": 23,
- "id": "missing-therapy",
+ "id": "ethical-assessment",
"metadata": {},
"outputs": [
{
@@ -640,7 +650,7 @@
{
"cell_type": "code",
"execution_count": 18,
- "id": "governmental-chorus",
+ "id": "greenhouse-response",
"metadata": {},
"outputs": [
{
@@ -680,7 +690,7 @@
{
"cell_type": "code",
"execution_count": 19,
- "id": "considered-dinner",
+ "id": "indian-mustang",
"metadata": {},
"outputs": [
{