Add patent-style non-zero initial NEAR for first strip

This commit is contained in:
2026-04-17 09:13:56 +08:00
parent 2e06705c86
commit 50539f4abb
5 changed files with 93 additions and 74 deletions

View File

@@ -99,14 +99,14 @@ module jls_near_ctrl #(
logic [47:0] pending_actual_bits_sum;
logic [47:0] pending_target_bits_sum;
logic pending_ratio_is_lossless_or_invalid;
logic pending_first_strip_update;
// Ratio classification.
logic ratio_is_lossless_or_invalid;
// Shift-add thresholds for the first-strip coarse jump. These are chosen to
// approximate the project review buckets while avoiding wide constant
// multipliers in the 250 MHz strip-control path.
// Patent-inspired non-zero initial NEAR lookup.
logic [3:0] ratio_for_initial_lookup;
logic [3:0] initial_near_level_next;
// Shift-add thresholds for the cumulative micro-adjustment path.
logic [47:0] target_plus_one_eighth;
logic [47:0] target_plus_one_thirtysecond;
logic [47:0] target_plus_one_quarter;
@@ -116,7 +116,6 @@ module jls_near_ctrl #(
logic [47:0] target_times_two;
logic [47:0] target_times_three;
logic [47:0] target_times_five;
logic [3:0] first_strip_level_next;
// Cumulative micro-adjust thresholds for later strips. +/-1/16 is the hold
// band; beyond +/-1/4 the controller skips one NEAR rung.
@@ -277,6 +276,46 @@ module jls_near_ctrl #(
endcase
end
always_comb begin
ratio_for_initial_lookup = active_ratio;
if (image_start_valid) begin
ratio_for_initial_lookup = image_ratio;
end
end
always_comb begin
initial_near_level_next = NEAR_LEVEL_0;
case (ratio_for_initial_lookup)
RATIO_1_TO_2: begin
if (PIX_WIDTH <= 8) begin
initial_near_level_next = NEAR_LEVEL_1;
end else begin
initial_near_level_next = NEAR_LEVEL_2;
end
end
RATIO_1_TO_4: begin
if (PIX_WIDTH <= 8) begin
initial_near_level_next = NEAR_LEVEL_16;
end else begin
initial_near_level_next = NEAR_LEVEL_255;
end
end
RATIO_1_TO_8: begin
if (PIX_WIDTH <= 8) begin
initial_near_level_next = NEAR_LEVEL_64;
end else begin
initial_near_level_next = NEAR_LEVEL_255;
end
end
default: begin
initial_near_level_next = NEAR_LEVEL_0;
end
endcase
end
always_comb begin
target_plus_one_thirtysecond = pending_target_bits_sum +
{5'b00000, pending_target_bits_sum[47:5]};
@@ -293,57 +332,6 @@ module jls_near_ctrl #(
target_times_five = pending_target_bits_sum + {pending_target_bits_sum[45:0], 2'b00};
end
always_comb begin
first_strip_level_next = NEAR_LEVEL_255;
case (active_ratio)
RATIO_1_TO_4, RATIO_1_TO_8: begin
if (pending_actual_bits_sum <= target_plus_one_eighth) begin
first_strip_level_next = NEAR_LEVEL_0;
end else if (pending_actual_bits_sum <= target_plus_one_quarter) begin
first_strip_level_next = NEAR_LEVEL_1;
end else if (pending_actual_bits_sum <= target_plus_one_half) begin
first_strip_level_next = NEAR_LEVEL_2;
end else if (pending_actual_bits_sum <= target_plus_three_quarters) begin
first_strip_level_next = NEAR_LEVEL_4;
end else if (pending_actual_bits_sum <= target_times_two_plus_quarter) begin
first_strip_level_next = NEAR_LEVEL_8;
end else if (pending_actual_bits_sum <= target_times_three) begin
first_strip_level_next = NEAR_LEVEL_32;
end else if (pending_actual_bits_sum <= {pending_target_bits_sum[45:0], 2'b00}) begin
first_strip_level_next = NEAR_LEVEL_64;
end else if (pending_actual_bits_sum <= ({pending_target_bits_sum[45:0], 2'b00} +
{pending_target_bits_sum[46:0], 1'b0})) begin
first_strip_level_next = NEAR_LEVEL_127;
end
end
default: begin
if (pending_actual_bits_sum <= target_plus_one_eighth) begin
first_strip_level_next = NEAR_LEVEL_0;
end else if (pending_actual_bits_sum <= target_plus_one_quarter) begin
first_strip_level_next = NEAR_LEVEL_1;
end else if (pending_actual_bits_sum <= target_plus_one_half) begin
first_strip_level_next = NEAR_LEVEL_2;
end else if (pending_actual_bits_sum <= target_times_two) begin
first_strip_level_next = NEAR_LEVEL_4;
end else if (pending_actual_bits_sum <= target_times_three) begin
first_strip_level_next = NEAR_LEVEL_8;
end else if (pending_actual_bits_sum <= target_times_five) begin
first_strip_level_next = NEAR_LEVEL_16;
end else if (pending_actual_bits_sum <= ({pending_target_bits_sum[45:0], 2'b00} +
{pending_target_bits_sum[46:0], 1'b0})) begin
first_strip_level_next = NEAR_LEVEL_32;
end else if (pending_actual_bits_sum <= ({pending_target_bits_sum[44:0], 3'b000} +
pending_target_bits_sum)) begin
first_strip_level_next = NEAR_LEVEL_64;
end else if (pending_actual_bits_sum <= ({pending_target_bits_sum[44:0], 3'b000} +
{pending_target_bits_sum[46:0], 1'b0})) begin
first_strip_level_next = NEAR_LEVEL_127;
end
end
endcase
end
always_comb begin
target_plus_sixteenth = pending_target_bits_sum + {4'b0000, pending_target_bits_sum[47:4]};
target_minus_sixteenth = pending_target_bits_sum - {4'b0000, pending_target_bits_sum[47:4]};
@@ -609,11 +597,10 @@ module jls_near_ctrl #(
pending_actual_bits_sum <= 48'd0;
pending_target_bits_sum <= 48'd0;
pending_ratio_is_lossless_or_invalid <= 1'b1;
pending_first_strip_update <= 1'b0;
end else begin
if (image_start_valid) begin
active_ratio <= image_ratio;
current_near_level <= NEAR_LEVEL_0;
current_near_level <= initial_near_level_next;
actual_bits_cumulative <= 48'd0;
target_bits_cumulative <= 48'd0;
target_miss_at_max_near <= 1'b0;
@@ -621,15 +608,12 @@ module jls_near_ctrl #(
pending_actual_bits_sum <= 48'd0;
pending_target_bits_sum <= 48'd0;
pending_ratio_is_lossless_or_invalid <= 1'b1;
pending_first_strip_update <= 1'b0;
end else if (pending_update_valid) begin
actual_bits_cumulative <= pending_actual_bits_sum;
target_bits_cumulative <= pending_target_bits_sum;
if (pending_ratio_is_lossless_or_invalid) begin
current_near_level <= NEAR_LEVEL_0;
end else if (pending_first_strip_update) begin
current_near_level <= first_strip_level_next;
end else begin
current_near_level <= adjusted_near_level_next;
end
@@ -644,8 +628,6 @@ module jls_near_ctrl #(
pending_actual_bits_sum <= actual_bits_sum;
pending_target_bits_sum <= target_bits_sum;
pending_ratio_is_lossless_or_invalid <= ratio_is_lossless_or_invalid;
pending_first_strip_update <= (actual_bits_cumulative == 48'd0) &&
(target_bits_cumulative == 48'd0);
end
end
end

View File

@@ -162,8 +162,11 @@ module jls_scan_ctrl #(
logic input_row_last_pixel;
// First-strip NEAR must be zero even if jls_near_ctrl has not yet reset on
// the same SOF pixel cycle.
// the same SOF pixel cycle. With the patent-inspired controller, the first
// strip may start from a non-zero initial NEAR chosen from active_ratio and
// PIX_WIDTH, so this logic computes the same initial rung locally.
logic [7:0] selected_strip_near;
logic [7:0] initial_strip_near;
always_comb begin
input_start_path_ready = 1'b1;
@@ -272,10 +275,43 @@ module jls_scan_ctrl #(
strip_height = SCAN_ROWS_VALUE;
end
always_comb begin
initial_strip_near = 8'd0;
case (active_ratio)
4'd1: begin
if (PIX_WIDTH <= 8) begin
initial_strip_near = 8'd1;
end else begin
initial_strip_near = 8'd2;
end
end
4'd2: begin
if (PIX_WIDTH <= 8) begin
initial_strip_near = 8'd16;
end else begin
initial_strip_near = 8'd255;
end
end
4'd3: begin
if (PIX_WIDTH <= 8) begin
initial_strip_near = 8'd64;
end else begin
initial_strip_near = 8'd255;
end
end
default: begin
initial_strip_near = 8'd0;
end
endcase
end
always_comb begin
selected_strip_near = current_near;
if (image_first_pixel) begin
selected_strip_near = 8'd0;
selected_strip_near = initial_strip_near;
end
end