From a3f07390e31ee8b8e3c5be5928a0f21b558e535a Mon Sep 17 00:00:00 2001 From: krisd Date: Sun, 20 Aug 2023 14:41:07 +1200 Subject: [PATCH] fixes #43: enforce hdmi 12px minimum control period during video and data-island preambles; fixed off-by-one errors on VG, VP, and VSync --- src/hdmi.sv | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/hdmi.sv b/src/hdmi.sv index 373c33c..2c91550 100644 --- a/src/hdmi.sv +++ b/src/hdmi.sv @@ -192,9 +192,9 @@ always_comb begin hsync <= invert ^ (cx >= screen_width + hsync_pulse_start && cx < screen_width + hsync_pulse_start + hsync_pulse_size); // vsync pulses should begin and end at the start of hsync, so special // handling is required for the lines on which vsync starts and ends - if (cy == screen_height + vsync_pulse_start) + if (cy == screen_height + vsync_pulse_start - 1) vsync <= invert ^ (cx >= screen_width + hsync_pulse_start); - else if (cy == screen_height + vsync_pulse_start + vsync_pulse_size) + else if (cy == screen_height + vsync_pulse_start + vsync_pulse_size - 1) vsync <= invert ^ (cx < screen_width + hsync_pulse_start); else vsync <= invert ^ (cy >= screen_height + vsync_pulse_start && cy < screen_height + vsync_pulse_start + vsync_pulse_size); @@ -254,8 +254,8 @@ generate end else begin - video_guard <= cx >= frame_width - 2 && cx < frame_width && (cy == frame_height - 1 || cy < screen_height); - video_preamble <= cx >= frame_width - 10 && cx < frame_width - 2 && (cy == frame_height - 1 || cy < screen_height); + video_guard <= cx >= frame_width - 2 && cx < frame_width && (cy == frame_height - 1 || cy < screen_height - 1 /* no VG at end of last line */); + video_preamble <= cx >= frame_width - 10 && cx < frame_width - 2 && (cy == frame_height - 1 || cy < screen_height - 1 /* no VP at end of last line */); end end @@ -264,7 +264,7 @@ generate logic [4:0] num_packets_alongside; always_comb begin - max_num_packets_alongside = ((frame_width - screen_width) /* VD period */ - 2 /* V guard */ - 8 /* V preamble */ - 12 /* 12px control period */ - 2 /* DI guard */ - 2 /* DI start guard */ - 8 /* DI premable */) / 32; + max_num_packets_alongside = (frame_width - screen_width /* VD period */ - 2 /* V guard */ - 8 /* V preamble */ - 4 /* Min V control period */ - 2 /* DI trailing guard */ - 2 /* DI leading guard */ - 8 /* DI premable */ - 4 /* Min DI control period */) / 32; if (max_num_packets_alongside > 18) num_packets_alongside = 5'd18; else @@ -272,9 +272,9 @@ generate end logic data_island_period_instantaneous; - assign data_island_period_instantaneous = num_packets_alongside > 0 && cx >= screen_width + 10 && cx < screen_width + 10 + num_packets_alongside * 32; + assign data_island_period_instantaneous = num_packets_alongside > 0 && cx >= screen_width + 14 && cx < screen_width + 14 + num_packets_alongside * 32; logic packet_enable; - assign packet_enable = data_island_period_instantaneous && 5'(cx + screen_width + 22) == 5'd0; + assign packet_enable = data_island_period_instantaneous && 5'(cx + screen_width + 18) == 5'd0; logic data_island_guard = 0; logic data_island_preamble = 0; @@ -289,8 +289,11 @@ generate end else begin - data_island_guard <= num_packets_alongside > 0 && ((cx >= screen_width + 8 && cx < screen_width + 10) || (cx >= screen_width + 10 + num_packets_alongside * 32 && cx < screen_width + 10 + num_packets_alongside * 32 + 2)); - data_island_preamble <= num_packets_alongside > 0 && cx >= screen_width && cx < screen_width + 8; + data_island_guard <= num_packets_alongside > 0 && ( + (cx >= screen_width + 12 && cx < screen_width + 14) /* leading guard */ || + (cx >= screen_width + 14 + num_packets_alongside * 32 && cx < screen_width + 14 + num_packets_alongside * 32 + 2) /* trailing guard */ + ); + data_island_preamble <= num_packets_alongside > 0 && cx >= screen_width + 4 && cx < screen_width + 12; data_island_period <= data_island_period_instantaneous; end end