diff --git a/fpga/srs/jpeg_ls.md b/fpga/srs/jpeg_ls.md index b298f84..1a70667 100644 --- a/fpga/srs/jpeg_ls.md +++ b/fpga/srs/jpeg_ls.md @@ -233,17 +233,29 @@ SOF 协议: - 当前实现采用离散 `NEAR` 档位集合 `{0, 1, 2, 4, 8, 16, 31}`,而不是逐条带线性 `+1/-1`。 - 第一条带结束后,控制器根据首条带 `actual_bits / target_bits` 的粗分档直接跳到 - 一个离散 `NEAR` 档位;当前 RTL 为便于时序收敛,采用移位加法近似阈值: - - `<= 1.125x target` -> `NEAR=0` - - `<= 1.25x target` -> `NEAR=1` - - `<= 1.5x target` -> `NEAR=2` - - `<= 2x target` -> `NEAR=4` - - `<= 3x target` -> `NEAR=8` - - `<= 5x target` -> `NEAR=16` - - `> 5x target` -> `NEAR=31` + 一个离散 `NEAR` 档位;当前 RTL 为便于时序收敛,采用移位加法近似阈值。 + - 对 `ratio=1:4/1:8`,首条带跳档更激进: + - `<= 1.125x target` -> `NEAR=0` + - `<= 1.25x target` -> `NEAR=1` + - `<= 1.5x target` -> `NEAR=2` + - `<= 1.75x target` -> `NEAR=4` + - `<= 2.25x target` -> `NEAR=8` + - `> 2.25x target` -> `NEAR=31` + - 对 `ratio=1:2`,保留较保守的中间档: + - `<= 1.125x target` -> `NEAR=0` + - `<= 1.25x target` -> `NEAR=1` + - `<= 1.5x target` -> `NEAR=2` + - `<= 2x target` -> `NEAR=4` + - `<= 3x target` -> `NEAR=8` + - `<= 5x target` -> `NEAR=16` + - `> 5x target` -> `NEAR=31` - 第二条带及后续条带使用累计 bit 偏差做离散档位微调,而不是重新全量估计: - - 若累计实际 bit 数 `> target + target/4`,档位 `+2` - - 若累计实际 bit 数 `> target + target/16`,档位 `+1` + - 对 `ratio=1:4/1:8`: + - 若累计实际 bit 数 `> target + target/8`,档位 `+2` + - 若累计实际 bit 数 `> target + target/32`,档位 `+1` + - 对 `ratio=1:2`: + - 若累计实际 bit 数 `> target + target/4`,档位 `+2` + - 若累计实际 bit 数 `> target + target/16`,档位 `+1` - 若累计实际 bit 数 `< target - target/4`,档位 `-2` - 若累计实际 bit 数 `< target - target/16`,档位 `-1` - 否则保持当前档位不变 diff --git a/fpga/verilog/jls_near_ctrl.sv b/fpga/verilog/jls_near_ctrl.sv index 6704192..7b23474 100644 --- a/fpga/verilog/jls_near_ctrl.sv +++ b/fpga/verilog/jls_near_ctrl.sv @@ -105,8 +105,11 @@ module jls_near_ctrl #( // approximate the project review buckets while avoiding wide constant // multipliers in the 250 MHz strip-control path. logic [47:0] target_plus_one_eighth; + logic [47:0] target_plus_one_thirtysecond; logic [47:0] target_plus_one_quarter; logic [47:0] target_plus_one_half; + logic [47:0] target_plus_three_quarters; + logic [47:0] target_times_two_plus_quarter; logic [47:0] target_times_two; logic [47:0] target_times_three; logic [47:0] target_times_five; @@ -260,29 +263,54 @@ module jls_near_ctrl #( end always_comb begin + target_plus_one_thirtysecond = pending_target_bits_sum + + {5'b00000, pending_target_bits_sum[47:5]}; target_plus_one_eighth = pending_target_bits_sum + {3'b000, pending_target_bits_sum[47:3]}; target_plus_one_quarter = pending_target_bits_sum + {2'b00, pending_target_bits_sum[47:2]}; target_plus_one_half = pending_target_bits_sum + {1'b0, pending_target_bits_sum[47:1]}; + target_plus_three_quarters = pending_target_bits_sum + + {1'b0, pending_target_bits_sum[47:1]} + + {2'b00, pending_target_bits_sum[47:2]}; target_times_two = {pending_target_bits_sum[46:0], 1'b0}; + target_times_two_plus_quarter = {pending_target_bits_sum[46:0], 1'b0} + + {2'b00, pending_target_bits_sum[47:2]}; target_times_three = pending_target_bits_sum + {pending_target_bits_sum[46:0], 1'b0}; 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_31; - 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 + 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 + 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 + end + endcase end always_comb begin @@ -294,16 +322,36 @@ module jls_near_ctrl #( always_comb begin step_up_one_level = 1'b0; - if (pending_actual_bits_sum > target_plus_sixteenth) begin - step_up_one_level = 1'b1; - end + case (active_ratio) + RATIO_1_TO_4, RATIO_1_TO_8: begin + if (pending_actual_bits_sum > target_plus_one_thirtysecond) begin + step_up_one_level = 1'b1; + end + end + + default: begin + if (pending_actual_bits_sum > target_plus_sixteenth) begin + step_up_one_level = 1'b1; + end + end + endcase end always_comb begin step_up_two_levels = 1'b0; - if (pending_actual_bits_sum > target_plus_quarter) begin - step_up_two_levels = 1'b1; - end + case (active_ratio) + RATIO_1_TO_4, RATIO_1_TO_8: begin + if (pending_actual_bits_sum > target_plus_one_eighth) begin + step_up_two_levels = 1'b1; + end + end + + default: begin + if (pending_actual_bits_sum > target_plus_quarter) begin + step_up_two_levels = 1'b1; + end + end + endcase end always_comb begin