Checkpoint JPEG-LS hardening and logs

Bundle SCAN_ROWS=64 RTL updates, refreshed CharLS reference streams, and a tracked checkpoint log with regression and quick-synth results.

Includes FSM safe-state hardening, control-path cleanup, and the latest quick synthesis snapshot on xc7vx690tffg1761-2.
This commit is contained in:
2026-04-17 18:05:48 +08:00
parent 50539f4abb
commit 9ace25b62b
93 changed files with 1005 additions and 392 deletions

View File

@@ -0,0 +1,124 @@
# JPEG-LS Checkpoint 2026-04-17
## Scope
This checkpoint bundles the current `SCAN_ROWS=64` RTL, the updated CharLS
reference codestream set, and the latest reliability-oriented hardening work:
- discrete `NEAR` coding-parameter / preset-parameter lookup tables
- strip-start staging between `jls_scan_ctrl` and top-level launch consumers
- reconstruction-wrap constant precompute (`RANGE_SCALE`)
- neighbor/history and header-path timing splits
- FSM safety hardening for the major control state machines
- cleanup of dead internal signals and ignored-interface plumbing
## Reliability Hardening
Safe-state synthesis attributes were added to the following state machines:
- `fpga/verilog/jls_golomb_encoder.sv`
- `fpga/verilog/jls_header_writer.sv`
- `fpga/verilog/jls_mode_router.sv`
- `fpga/verilog/jls_regular_error_quantizer.sv`
- `fpga/verilog/jls_run_mode.sv`
- `fpga/verilog/jpeg_ls_encoder_top.sv`
Additional hardening / cleanup in this checkpoint:
- state return guard added for `jls_run_mode.state_after_run_code`
- dead internal signals removed from `jls_neighbor_provider`, `jls_context_model`
- ignored top-level / spare inputs are now explicitly observed where needed to
avoid ambiguous synthesis behavior
- `jls_output_buffer` no longer carries meaningless reserved input ports
## Functional Regression
### Basic smoke tests
Executed without rerunning the full pattern regression:
- `tb_jls_header_writer`: PASS
- `tb_jls_context_update`: PASS
- `tb_jpeg_ls_encoder_top_run_smoke`: PASS
- `tb_jpeg_ls_encoder_top_run_smoke` 8-bit two-strip ratio=2 case: PASS
- dynamic-NEAR validation on `rtl_top_ramp_8b_2strip_ratio2.jls`: PASS
Observed dynamic-NEAR result for the 8-bit two-strip ratio=2 smoke:
- frame count: `2`
- `NEAR` sequence: `16 / 32`
- overall max abs diff: `32`
- target ratio check: PASS
### Full pattern regression status carried forward
Current `SCAN_ROWS=64` full pattern regression summary:
- ratio `1:1`: `17 PASS / 0 FAIL`
- ratio `2:1`: `16 PASS / 1 FAIL`
- ratio `4:1`: `14 PASS / 3 FAIL`
- ratio `8:1`: `13 PASS / 4 FAIL`
Known target-ratio misses from the carried-forward regression set:
- `2:1`
- `omaha-w6144-h256-s0-b16`
- `4:1`
- `omaha-w6144-h256-s0-b16`
- `sena-w6144-h256-s0-b16`
- `sensin-w6144-h256-s0-b16`
- `8:1`
- `omaha-w6144-h256-s0-b16`
- `sena-w6144-h256-s0-b16`
- `sensin-w6144-h256-s0-b16`
- `sinan-w6144-h256-s0-b16`
## Quick Synthesis
### Configuration
- tool: Vivado 2023.2
- part: `xc7vx690tffg1761-2`
- top: `jpeg_ls_encoder_top`
- clock target: `4.000 ns` (`250 MHz`)
- mode: out-of-context quick synthesis
### Result
- WNS: `-0.677 ns`
- estimated Fmax: about `215.2 MHz`
### Current worst path
Latest quick-synth worst path after the reliability-hardening changes:
- source: `context_model_i/context_model_idle_reg_reg`
- destination: `run_mode_i/FSM_hamming2_state_reg[*]/CE`
- logic levels: `11`
This means the earlier very deep generic control/data paths were eliminated, but
the current worst case is still above the earlier temporary `<=7` goal after
FSM-safe encoding was enabled.
### Resource snapshot
- Slice LUTs: `25949`
- Slice Registers: `8713`
- Block RAM Tile: `3.5`
- DSP: `6`
## Synthesis Notes
The latest quick synthesis run reported:
- `0` errors
- `0` critical warnings
- `32` warnings
Important observation from the Vivado log:
- safe-state handling was implemented for the hardened FSMs
Residual warnings are now dominated by synthesis hygiene items rather than
functional blockers. The current checkpoint stops here intentionally without
more timing optimization or compression-ratio tuning.

View File

@@ -32,7 +32,7 @@ Parameters:
| `DEFAULT_PIC_ROW` | 256 | Default image height used when runtime dimensions are invalid. |
| `MAX_PIC_COL` | 6144 | Maximum supported runtime image width. |
| `MAX_PIC_ROW` | 4096 | Maximum supported runtime image height. |
| `SCAN_ROWS` | 16 | Number of source rows in one standalone JPEG-LS strip frame. |
| `SCAN_ROWS` | 64 | Number of source rows in one standalone JPEG-LS strip frame. |
| `MAX_NEAR` | 31 | Maximum dynamic NEAR value. |
| `OUT_BUF_BYTES` | 8192 | Internal byte output buffer size. |
| `OUT_BUF_AFULL_MARGIN` | 256 | Input pause margin for the internal output buffer. |

View File

@@ -54,6 +54,7 @@ $RepoRoot = (Resolve-Path ".").Path
$OutDir = Join-Path $RepoRoot ("tools\jls_compat\out\pattern_regression_cr" + $ConfiguredCompressionRatio)
$DepPath = Join-Path $RepoRoot "tools\jls_compat\.deps"
$SummaryCsv = Join-Path $OutDir "pattern_regression_summary.csv"
$ScanRows = 64
$QuestaBin = "C:\questasim64_2020.1\win64"
$VlogExe = Join-Path $QuestaBin "vlog.exe"
$VsimExe = Join-Path $QuestaBin "vsim.exe"
@@ -160,7 +161,7 @@ foreach ($PatternFile in $PatternFiles) {
$RtlJls = Join-Path $OutDir ($CaseName + ".rtljls")
$TranscriptLog = Join-Path $OutDir ($CaseName + ".vsim.log")
$CaseJson = Join-Path $OutDir ($CaseName + ".summary.json")
$ExpectedFrames = [int]($Height / 16)
$ExpectedFrames = [int]($Height / $ScanRows)
$VsimArgs = @(
"-c",
@@ -168,6 +169,7 @@ foreach ($PatternFile in $PatternFiles) {
"-gPIX_WIDTH=16",
("-gPIC_COL=" + $Width),
("-gPIC_ROW=" + $Height),
("-gSCAN_ROWS=" + $ScanRows),
("+IN_PGM=" + (To-PosixPath $SourcePgm)),
("+RATIO=" + $RtlRatioPort),
("+OUT=" + (To-PosixPath $RtlJls)),

View File

@@ -10,7 +10,7 @@ param(
[int] $Width = 6144,
[int] $Height = 256,
[int] $ImageCount = 10,
[int] $ScanRows = 16,
[int] $ScanRows = 64,
# PATTERN=9 rotates ten deterministic representative images.
[int] $Pattern = 9,

View File

@@ -95,11 +95,13 @@ foreach ($Bits in @(8, 10, 12, 14, 16)) {
$JlsPlusArg = "+OUT=tools/jls_compat/out/$Stem.jls"
$PatternPlusArg = "+PATTERN=$Pattern"
$WidthGeneric = "-gPIX_WIDTH=$Bits"
$HeightGeneric = "-gPIC_ROW=16"
$ScanRowsGeneric = "-gSCAN_ROWS=16"
Write-Pgm $PgmPath $Pattern $Bits 16 16
Invoke-CheckedCommand "run RTL top compatibility smoke: ${Bits}b $PatternName image" {
vsim -c tb_jpeg_ls_encoder_top_run_smoke $WidthGeneric $PatternPlusArg $JlsPlusArg -do "run -all; quit"
vsim -c tb_jpeg_ls_encoder_top_run_smoke $WidthGeneric $HeightGeneric $ScanRowsGeneric $PatternPlusArg $JlsPlusArg -do "run -all; quit"
}
Invoke-CheckedCommand "decode ${Bits}b $PatternName RTL output with CharLS and compare reference PGM" {
@@ -114,7 +116,7 @@ $CheckerPgmPath = Join-Path $OutDir "$CheckerStem.pgm"
Write-Pgm $CheckerPgmPath 2 8 16 16
Invoke-CheckedCommand "run RTL top compatibility smoke: 8b checker image" {
vsim -c tb_jpeg_ls_encoder_top_run_smoke -gPIX_WIDTH=8 +PATTERN=2 +OUT=tools/jls_compat/out/$CheckerStem.jls -do "run -all; quit"
vsim -c tb_jpeg_ls_encoder_top_run_smoke -gPIX_WIDTH=8 -gPIC_ROW=16 -gSCAN_ROWS=16 +PATTERN=2 +OUT=tools/jls_compat/out/$CheckerStem.jls -do "run -all; quit"
}
Invoke-CheckedCommand "decode 8b checker RTL output with CharLS and compare reference PGM" {
@@ -127,7 +129,7 @@ $MultiStripPgmPath = Join-Path $OutDir "$MultiStripStem.pgm"
Write-Pgm $MultiStripPgmPath 1 8 16 32
Invoke-CheckedCommand "run RTL top compatibility smoke: 8b ramp two-strip image" {
vsim -c tb_jpeg_ls_encoder_top_run_smoke -gPIX_WIDTH=8 -gPIC_ROW=32 +PATTERN=1 +OUT=tools/jls_compat/out/$MultiStripStem.jls -do "run -all; quit"
vsim -c tb_jpeg_ls_encoder_top_run_smoke -gPIX_WIDTH=8 -gPIC_ROW=32 -gSCAN_ROWS=16 +PATTERN=1 +OUT=tools/jls_compat/out/$MultiStripStem.jls -do "run -all; quit"
}
Invoke-CheckedCommand "decode 8b ramp two-strip RTL output with CharLS and compare reference PGM" {
@@ -140,7 +142,7 @@ $MultiImagePgmPath = Join-Path $OutDir "$MultiImageStem.pgm"
Write-Pgm $MultiImagePgmPath 0 8 16 32
Invoke-CheckedCommand "run RTL top compatibility smoke: 8b zero two-image stream" {
vsim -c tb_jpeg_ls_encoder_top_run_smoke -gPIX_WIDTH=8 -gIMAGE_COUNT=2 +PATTERN=0 +OUT=tools/jls_compat/out/$MultiImageStem.jls -do "run -all; quit"
vsim -c tb_jpeg_ls_encoder_top_run_smoke -gPIX_WIDTH=8 -gPIC_ROW=16 -gSCAN_ROWS=16 -gIMAGE_COUNT=2 +PATTERN=0 +OUT=tools/jls_compat/out/$MultiImageStem.jls -do "run -all; quit"
}
Invoke-CheckedCommand "decode 8b zero two-image RTL output with CharLS and compare stitched reference PGM" {
@@ -153,7 +155,7 @@ $NearStripPgmPath = Join-Path $OutDir "$NearStripStem.pgm"
Write-Pgm $NearStripPgmPath 1 8 16 32
Invoke-CheckedCommand "run RTL top compatibility smoke: 8b ramp two-strip ratio=2 image" {
vsim -c tb_jpeg_ls_encoder_top_run_smoke -gPIX_WIDTH=8 -gPIC_ROW=32 +PATTERN=1 +RATIO=2 +OUT=tools/jls_compat/out/$NearStripStem.jls -do "run -all; quit"
vsim -c tb_jpeg_ls_encoder_top_run_smoke -gPIX_WIDTH=8 -gPIC_ROW=32 -gSCAN_ROWS=16 +PATTERN=1 +RATIO=2 +OUT=tools/jls_compat/out/$NearStripStem.jls -do "run -all; quit"
}
Invoke-CheckedCommand "decode 8b ramp two-strip ratio=2 RTL output with CharLS and compare reference PGM within NEAR bound" {

View File

@@ -3,7 +3,7 @@
// Figure : N/A
// Table : N/A
// Pseudocode : Small all-zero image exercises run-mode strip closure
// Example : 16x16 zero image should produce SOI ... EOI and one original
// Example : 16x64 zero image should produce SOI ... EOI and one original
// image-start sideband byte.
//
// Non-empty top-level smoke. This is a tiny compatibility-oriented smoke for
@@ -31,8 +31,8 @@ module tb_jpeg_ls_encoder_top_run_smoke;
// PIX_WIDTH to cover the other required grayscale precisions.
parameter int PIX_WIDTH = 8;
parameter int PIC_COL = 16;
parameter int PIC_ROW = 16;
parameter int SCAN_ROWS = 16;
parameter int PIC_ROW = 64;
parameter int SCAN_ROWS = 64;
parameter int IMAGE_COUNT = 1;
parameter int TIMEOUT_PER_PIXEL = 512;
localparam int IFIFO_DATA_WIDTH = ((PIX_WIDTH + 7) / 8) * 9;

View File

@@ -83,7 +83,7 @@ imagecodecs/CharLS 2.4.1 验证:原始单 component 码流可解码,在同
| `DEFAULT_PIC_ROW` | int | 256 | 16..4096 | 默认图像高度 |
| `MAX_PIC_COL` | int | 6144 | 6144 | 最大图像宽度 |
| `MAX_PIC_ROW` | int | 4096 | 4096 | 最大图像高度 |
| `SCAN_ROWS` | int | 16 | 1..4096 | 每个条带 frame 的行数 |
| `SCAN_ROWS` | int | 64 | 1..4096 | 每个条带 frame 的行数 |
| `MAX_NEAR` | int | 31 | 31 | 动态 `NEAR` 最大值 |
| `OUT_BUF_BYTES` | int | 8192 | 实现相关 | 内部输出缓冲字节数 |
| `OUT_BUF_AFULL_MARGIN` | int | 256 | 实现相关 | 输出缓冲暂停输入的余量 |

View File

@@ -4,12 +4,12 @@
// Table : N/A
// Pseudocode : RANGE, qbpp, and LIMIT derivation from MAXVAL and NEAR
// Trace : docs/jls_traceability.md#jls-coding-parameters
// Example : PIX_WIDTH=8,NEAR=0 gives RANGE=256,qbpp=8,LIMIT=32.
// Example : PIX_WIDTH=16 and NEAR=64 gives RANGE=510, qbpp=9, LIMIT=64.
//
// JPEG-LS coding parameter helper. RANGE depends on NEAR through
// RANGE = floor((MAXVAL + 2*NEAR)/(2*NEAR+1)) + 1. This is a strip-level
// control path, so the generic arithmetic is acceptable here and keeps the
// pixel pipeline free from runtime division logic.
// JPEG-LS coding parameter helper. The project NEAR controller only emits a
// discrete ladder {0,1,2,4,8,16,32,64,127,255}. A direct table lookup keeps
// strip-start timing shallow and removes the long carry-chain path that the
// generic Annex G.2 arithmetic created in synthesis.
`default_nettype none
@@ -26,126 +26,352 @@ module jls_coding_params #(
// JPEG-LS quantized bits per sample, ceil(log2(RANGE)).
output logic [4:0] qbpp,
// Precomputed RANGE * (2*NEAR+1) used by Annex A.5 reconstruction wrap.
output logic [16:0] RANGE_SCALE,
// JPEG-LS LIMIT parameter used by regular-mode Golomb coding.
output logic [6:0] LIMIT
);
integer maximum_sample_value_int;
integer maximum_near_int;
integer near_clamped_int;
integer denominator_int;
integer range_int;
integer qbpp_int;
integer limit_int;
always_comb begin
maximum_sample_value_int = 65535;
limit_int = 64;
RANGE = 17'd65536;
qbpp = 5'd16;
RANGE_SCALE = 17'd65536;
LIMIT = 7'd64;
case (PIX_WIDTH)
8: begin
maximum_sample_value_int = 255;
limit_int = 32;
LIMIT = 7'd32;
case (NEAR)
8'd0: begin
RANGE = 17'd256;
qbpp = 5'd8;
RANGE_SCALE = 17'd256;
end
8'd1: begin
RANGE = 17'd86;
qbpp = 5'd7;
RANGE_SCALE = 17'd258;
end
8'd2: begin
RANGE = 17'd52;
qbpp = 5'd6;
RANGE_SCALE = 17'd260;
end
8'd4: begin
RANGE = 17'd30;
qbpp = 5'd5;
RANGE_SCALE = 17'd270;
end
8'd8: begin
RANGE = 17'd16;
qbpp = 5'd4;
RANGE_SCALE = 17'd272;
end
8'd16: begin
RANGE = 17'd9;
qbpp = 5'd4;
RANGE_SCALE = 17'd297;
end
8'd31: begin
RANGE = 17'd6;
qbpp = 5'd3;
RANGE_SCALE = 17'd378;
end
8'd32: begin
RANGE = 17'd5;
qbpp = 5'd3;
RANGE_SCALE = 17'd325;
end
8'd63: begin
RANGE = 17'd4;
qbpp = 5'd2;
RANGE_SCALE = 17'd508;
end
8'd64: begin
RANGE = 17'd3;
qbpp = 5'd2;
RANGE_SCALE = 17'd387;
end
8'd127: begin
RANGE = 17'd2;
qbpp = 5'd1;
RANGE_SCALE = 17'd510;
end
default: begin
RANGE = 17'd2;
qbpp = 5'd1;
RANGE_SCALE = 17'd510;
end
endcase
end
10: begin
maximum_sample_value_int = 1023;
limit_int = 40;
LIMIT = 7'd40;
case (NEAR)
8'd0: begin
RANGE = 17'd1024;
qbpp = 5'd10;
RANGE_SCALE = 17'd1024;
end
8'd1: begin
RANGE = 17'd342;
qbpp = 5'd9;
RANGE_SCALE = 17'd1026;
end
8'd2: begin
RANGE = 17'd206;
qbpp = 5'd8;
RANGE_SCALE = 17'd1030;
end
8'd4: begin
RANGE = 17'd115;
qbpp = 5'd7;
RANGE_SCALE = 17'd1035;
end
8'd8: begin
RANGE = 17'd62;
qbpp = 5'd6;
RANGE_SCALE = 17'd1054;
end
8'd16: begin
RANGE = 17'd32;
qbpp = 5'd5;
RANGE_SCALE = 17'd1056;
end
8'd31: begin
RANGE = 17'd18;
qbpp = 5'd5;
RANGE_SCALE = 17'd1134;
end
8'd32: begin
RANGE = 17'd17;
qbpp = 5'd5;
RANGE_SCALE = 17'd1105;
end
8'd63: begin
RANGE = 17'd10;
qbpp = 5'd4;
RANGE_SCALE = 17'd1270;
end
8'd64: begin
RANGE = 17'd9;
qbpp = 5'd4;
RANGE_SCALE = 17'd1161;
end
8'd127: begin
RANGE = 17'd6;
qbpp = 5'd3;
RANGE_SCALE = 17'd1530;
end
default: begin
RANGE = 17'd4;
qbpp = 5'd2;
RANGE_SCALE = 17'd2044;
end
endcase
end
12: begin
maximum_sample_value_int = 4095;
limit_int = 48;
LIMIT = 7'd48;
case (NEAR)
8'd0: begin
RANGE = 17'd4096;
qbpp = 5'd12;
RANGE_SCALE = 17'd4096;
end
8'd1: begin
RANGE = 17'd1366;
qbpp = 5'd11;
RANGE_SCALE = 17'd4098;
end
8'd2: begin
RANGE = 17'd820;
qbpp = 5'd10;
RANGE_SCALE = 17'd4100;
end
8'd4: begin
RANGE = 17'd456;
qbpp = 5'd9;
RANGE_SCALE = 17'd4104;
end
8'd8: begin
RANGE = 17'd242;
qbpp = 5'd8;
RANGE_SCALE = 17'd4114;
end
8'd16: begin
RANGE = 17'd126;
qbpp = 5'd7;
RANGE_SCALE = 17'd4158;
end
8'd31: begin
RANGE = 17'd66;
qbpp = 5'd7;
RANGE_SCALE = 17'd4158;
end
8'd32: begin
RANGE = 17'd64;
qbpp = 5'd6;
RANGE_SCALE = 17'd4160;
end
8'd63: begin
RANGE = 17'd34;
qbpp = 5'd6;
RANGE_SCALE = 17'd4318;
end
8'd64: begin
RANGE = 17'd33;
qbpp = 5'd6;
RANGE_SCALE = 17'd4257;
end
8'd127: begin
RANGE = 17'd18;
qbpp = 5'd5;
RANGE_SCALE = 17'd4590;
end
default: begin
RANGE = 17'd10;
qbpp = 5'd4;
RANGE_SCALE = 17'd5110;
end
endcase
end
14: begin
maximum_sample_value_int = 16383;
limit_int = 56;
LIMIT = 7'd56;
case (NEAR)
8'd0: begin
RANGE = 17'd16384;
qbpp = 5'd14;
RANGE_SCALE = 17'd16384;
end
8'd1: begin
RANGE = 17'd5462;
qbpp = 5'd13;
RANGE_SCALE = 17'd16386;
end
8'd2: begin
RANGE = 17'd3278;
qbpp = 5'd12;
RANGE_SCALE = 17'd16390;
end
8'd4: begin
RANGE = 17'd1822;
qbpp = 5'd11;
RANGE_SCALE = 17'd16398;
end
8'd8: begin
RANGE = 17'd965;
qbpp = 5'd10;
RANGE_SCALE = 17'd16405;
end
8'd16: begin
RANGE = 17'd498;
qbpp = 5'd9;
RANGE_SCALE = 17'd16434;
end
8'd31: begin
RANGE = 17'd262;
qbpp = 5'd9;
RANGE_SCALE = 17'd16506;
end
8'd32: begin
RANGE = 17'd254;
qbpp = 5'd8;
RANGE_SCALE = 17'd16510;
end
8'd63: begin
RANGE = 17'd130;
qbpp = 5'd8;
RANGE_SCALE = 17'd16510;
end
8'd64: begin
RANGE = 17'd128;
qbpp = 5'd7;
RANGE_SCALE = 17'd16512;
end
8'd127: begin
RANGE = 17'd66;
qbpp = 5'd7;
RANGE_SCALE = 17'd16830;
end
default: begin
RANGE = 17'd34;
qbpp = 5'd6;
RANGE_SCALE = 17'd17374;
end
endcase
end
default: begin
maximum_sample_value_int = 65535;
limit_int = 64;
LIMIT = 7'd64;
case (NEAR)
8'd0: begin
RANGE = 17'd65536;
qbpp = 5'd16;
RANGE_SCALE = 17'd65536;
end
8'd1: begin
RANGE = 17'd21846;
qbpp = 5'd15;
RANGE_SCALE = 17'd65538;
end
8'd2: begin
RANGE = 17'd13108;
qbpp = 5'd14;
RANGE_SCALE = 17'd65540;
end
8'd4: begin
RANGE = 17'd7283;
qbpp = 5'd13;
RANGE_SCALE = 17'd65547;
end
8'd8: begin
RANGE = 17'd3856;
qbpp = 5'd12;
RANGE_SCALE = 17'd65552;
end
8'd16: begin
RANGE = 17'd1987;
qbpp = 5'd11;
RANGE_SCALE = 17'd65571;
end
8'd31: begin
RANGE = 17'd1042;
qbpp = 5'd11;
RANGE_SCALE = 17'd65646;
end
8'd32: begin
RANGE = 17'd1010;
qbpp = 5'd10;
RANGE_SCALE = 17'd65650;
end
8'd63: begin
RANGE = 17'd518;
qbpp = 5'd10;
RANGE_SCALE = 17'd65786;
end
8'd64: begin
RANGE = 17'd510;
qbpp = 5'd9;
RANGE_SCALE = 17'd65790;
end
8'd127: begin
RANGE = 17'd258;
qbpp = 5'd9;
RANGE_SCALE = 17'd65790;
end
default: begin
RANGE = 17'd130;
qbpp = 5'd8;
RANGE_SCALE = 17'd66430;
end
endcase
end
endcase
end
always_comb begin
maximum_near_int = maximum_sample_value_int / 2;
if (maximum_near_int > 255) begin
maximum_near_int = 255;
end
end
always_comb begin
near_clamped_int = NEAR;
if (near_clamped_int > maximum_near_int) begin
near_clamped_int = maximum_near_int;
end
end
always_comb begin
denominator_int = (2 * near_clamped_int) + 1;
range_int = ((maximum_sample_value_int + (2 * near_clamped_int)) / denominator_int) + 1;
end
always_comb begin
qbpp_int = 0;
if (range_int > 1) begin
qbpp_int = 1;
if (range_int > 2) begin
qbpp_int = 2;
end
if (range_int > 4) begin
qbpp_int = 3;
end
if (range_int > 8) begin
qbpp_int = 4;
end
if (range_int > 16) begin
qbpp_int = 5;
end
if (range_int > 32) begin
qbpp_int = 6;
end
if (range_int > 64) begin
qbpp_int = 7;
end
if (range_int > 128) begin
qbpp_int = 8;
end
if (range_int > 256) begin
qbpp_int = 9;
end
if (range_int > 512) begin
qbpp_int = 10;
end
if (range_int > 1024) begin
qbpp_int = 11;
end
if (range_int > 2048) begin
qbpp_int = 12;
end
if (range_int > 4096) begin
qbpp_int = 13;
end
if (range_int > 8192) begin
qbpp_int = 14;
end
if (range_int > 16384) begin
qbpp_int = 15;
end
if (range_int > 32768) begin
qbpp_int = 16;
end
end
end
always_comb begin
RANGE = range_int[16:0];
qbpp = qbpp_int[4:0];
LIMIT = limit_int[6:0];
end
endmodule
`default_nettype wire

View File

@@ -100,7 +100,6 @@ module jls_context_model #(
logic pending_strip_first_pixel;
logic pending_strip_last_pixel;
logic [PIX_WIDTH-1:0] pending_Px;
logic [8:0] pending_context_index;
logic pending_context_negative;
logic pending_run_mode_context;
@@ -693,7 +692,6 @@ module jls_context_model #(
pending_strip_first_pixel <= 1'b0;
pending_strip_last_pixel <= 1'b0;
pending_Px <= {PIX_WIDTH{1'b0}};
pending_context_index <= 9'd0;
pending_context_negative <= 1'b0;
pending_run_mode_context <= 1'b0;
pending_bypass_valid <= 1'b0;
@@ -737,7 +735,6 @@ module jls_context_model #(
pending_strip_first_pixel <= issue_slot_strip_first_pixel;
pending_strip_last_pixel <= issue_slot_strip_last_pixel;
pending_Px <= issue_slot_Px;
pending_context_index <= issue_slot_context_index;
pending_context_negative <= issue_slot_context_negative;
pending_run_mode_context <= issue_slot_run_mode_context;
pending_bypass_valid <= issue_slot_bypass_valid;

View File

@@ -83,11 +83,11 @@ module jls_context_update (
// Signed and absolute forms of Errval.
logic signed [32:0] Errval_ext;
logic [32:0] abs_Errval_ext;
logic [31:0] abs_Errval_ext;
// Stage-1 update terms from Annex A.6.
logic signed [9:0] near_scale;
logic signed [40:0] B_delta;
(* use_dsp = "yes" *) logic signed [40:0] B_delta;
logic [31:0] A_accum_next;
logic signed [40:0] B_accum_next;
logic [15:0] N_halved_plus_one_next;
@@ -287,21 +287,16 @@ module jls_context_update (
logic result_promote_next;
// Shared narrow-scale multiplier for Annex A.6 Errval*(2*NEAR+1).
jls_near_scale_mul #(
.INPUT_WIDTH(33),
.OUTPUT_WIDTH(41)
) context_update_near_scale_mul_i (
.multiplicand_i(s1_Errval_ext),
.near_scale_i(s1_near_scale[8:0]),
.product_o(B_delta)
);
always_comb begin
B_delta = s1_Errval_ext * $signed(s1_near_scale[8:0]);
end
always_comb begin
Errval_ext = {s0_Errval[31], s0_Errval};
end
always_comb begin
abs_Errval_ext = Errval_ext[32:0];
abs_Errval_ext = Errval_ext[31:0];
if (Errval_ext < 33'sd0) begin
abs_Errval_ext = -Errval_ext;
end

View File

@@ -64,9 +64,9 @@ module jls_error_mapper (
// Source value after optional context correction.
logic signed [31:0] corrected_Errval;
logic signed [32:0] corrected_Errval_ext;
logic signed [32:0] abs_Errval_ext;
logic [32:0] MErrval_ext;
logic signed [31:0] corrected_Errval_ext;
logic [31:0] abs_Errval_ext;
logic [31:0] MErrval_ext;
// Handshake terms.
logic slot_open;
@@ -80,7 +80,7 @@ module jls_error_mapper (
end
always_comb begin
corrected_Errval_ext = {corrected_Errval[31], corrected_Errval};
corrected_Errval_ext = corrected_Errval;
end
always_comb begin
@@ -91,9 +91,9 @@ module jls_error_mapper (
end
always_comb begin
MErrval_ext = abs_Errval_ext[32:0] << 1;
if (corrected_Errval_ext < 33'sd0) begin
MErrval_ext = (abs_Errval_ext[32:0] << 1) - 33'd1;
MErrval_ext = abs_Errval_ext << 1;
if (corrected_Errval_ext < 32'sd0) begin
MErrval_ext = (abs_Errval_ext << 1) - 32'd1;
end
end
@@ -130,7 +130,7 @@ module jls_error_mapper (
if (accept_err) begin
mapped_valid <= 1'b1;
MErrval <= MErrval_ext[31:0];
MErrval <= MErrval_ext;
mapped_k <= k;
mapped_limit <= limit;
mapped_qbpp <= qbpp;

View File

@@ -78,7 +78,7 @@ module jls_golomb_encoder #(
localparam logic [6:0] MAX_CODE_BITS_VALUE = MAX_CODE_BITS;
// Current state.
golomb_state_e state;
(* fsm_safe_state = "reset_state" *) golomb_state_e state;
// Latched coding parameters for the active mapped-error event.
logic [6:0] prefix_remaining;

View File

@@ -98,7 +98,7 @@ module jls_header_writer #(
} header_state_e;
// Current and next state for marker emission.
header_state_e state;
(* fsm_safe_state = "reset_state" *) header_state_e state;
header_state_e state_next;
// Byte indexes inside the header and EOI byte sequences.
@@ -202,7 +202,7 @@ module jls_header_writer #(
always_comb begin
header_byte_index = header_index;
if (state == STATE_IDLE && accept_start) begin
if (state == STATE_HEADER && !byte_valid) begin
header_byte_index = 6'd0;
end else if (state == STATE_HEADER && output_fire && header_index != HEADER_LAST_INDEX) begin
header_byte_index = header_index + 6'd1;
@@ -337,18 +337,22 @@ module jls_header_writer #(
byte_valid_next = 1'b0;
byte_data_next = 8'h00;
original_image_start_next = 1'b0;
if (accept_start) begin
byte_valid_next = 1'b1;
byte_data_next = header_byte;
original_image_start_next = original_image_first_strip;
end else if (accept_finish) begin
if (accept_finish) begin
byte_valid_next = 1'b1;
byte_data_next = eoi_byte;
end
end
STATE_HEADER: begin
if (output_fire) begin
if (!byte_valid) begin
byte_valid_next = 1'b1;
byte_data_next = header_byte;
if (latched_original_image_first_strip) begin
original_image_start_next = 1'b1;
end else begin
original_image_start_next = 1'b0;
end
end else if (output_fire) begin
if (header_index == HEADER_LAST_INDEX) begin
byte_valid_next = 1'b0;
byte_data_next = 8'h00;

View File

@@ -29,7 +29,7 @@ module jls_input_ctrl #(
parameter int MAX_PIC_ROW = 4096,
// Number of original-image rows in one standalone JPEG-LS strip frame.
parameter int SCAN_ROWS = 16,
parameter int SCAN_ROWS = 64,
// Packed input FIFO width: one SOF sideband bit per input byte lane.
parameter int IFIFO_DATA_WIDTH = ((PIX_WIDTH + 7) / 8) * 9
@@ -149,6 +149,7 @@ module jls_input_ctrl #(
// Decoded fields from the FIFO data word.
logic fifo_word_sof;
logic [PIX_WIDTH-1:0] fifo_word_sample;
(* keep = "true" *) logic fifo_word_spare_observed;
// Coordinate boundary signals for the next accepted in-frame pixel.
logic [12:0] active_pic_col_last;
@@ -165,6 +166,13 @@ module jls_input_ctrl #(
assign fifo_word_sof = ififo_rdata[SOF_BIT_INDEX];
assign fifo_word_sample = ififo_rdata[PIX_WIDTH-1:0];
always_comb begin
fifo_word_spare_observed = 1'b0;
if (PIX_WIDTH != 8) begin
fifo_word_spare_observed = ififo_rdata[16];
end
end
always_comb begin
cfg_col_in_range = 1'b0;
if (cfg_pic_col >= MIN_PIC_COL_VALUE && cfg_pic_col <= MAX_PIC_COL_VALUE) begin

View File

@@ -102,7 +102,7 @@ module jls_mode_router #(
EVENT_INTERRUPT = 2'd3
} event_kind_e;
router_state_e state;
(* fsm_safe_state = "reset_state" *) router_state_e state;
event_kind_e event_kind;
event_kind_e event_kind_next;

View File

@@ -84,7 +84,7 @@ module jls_near_ctrl #(
logic [3:0] current_near_level;
// Strip-level source and target bit calculations.
logic [47:0] strip_pixel_count_ext;
logic [43:0] strip_pixel_count_ext;
logic [47:0] strip_source_bits;
logic [47:0] strip_target_bits;
logic [47:0] strip_actual_bits;
@@ -189,38 +189,38 @@ module jls_near_ctrl #(
end
always_comb begin
strip_pixel_count_ext = {16'd0, strip_pixel_count};
strip_pixel_count_ext = {12'd0, strip_pixel_count};
end
always_comb begin
strip_source_bits = {48{1'b0}};
case (PIX_WIDTH)
8: begin
strip_source_bits = {strip_pixel_count_ext[44:0], 3'b000};
strip_source_bits = {strip_pixel_count_ext, 4'd0};
end
10: begin
strip_source_bits = {strip_pixel_count_ext[44:0], 3'b000} +
{strip_pixel_count_ext[46:0], 1'b0};
strip_source_bits = {strip_pixel_count_ext, 4'd0} +
{2'd0, strip_pixel_count_ext, 2'd0};
end
12: begin
strip_source_bits = {strip_pixel_count_ext[44:0], 3'b000} +
{strip_pixel_count_ext[45:0], 2'b00};
strip_source_bits = {strip_pixel_count_ext, 4'd0} +
{1'd0, strip_pixel_count_ext, 3'd0};
end
14: begin
strip_source_bits = {strip_pixel_count_ext[44:0], 3'b000} +
{strip_pixel_count_ext[45:0], 2'b00} +
{strip_pixel_count_ext[46:0], 1'b0};
strip_source_bits = {strip_pixel_count_ext, 4'd0} +
{1'd0, strip_pixel_count_ext, 3'd0} +
{2'd0, strip_pixel_count_ext, 2'd0};
end
16: begin
strip_source_bits = {strip_pixel_count_ext[43:0], 4'b0000};
strip_source_bits = {strip_pixel_count_ext, 4'd0};
end
default: begin
strip_source_bits = {strip_pixel_count_ext[43:0], 4'b0000};
strip_source_bits = {strip_pixel_count_ext, 4'd0};
end
endcase
end

View File

@@ -84,10 +84,9 @@ module jls_neighbor_provider #(
// This provider is waiting for the current reconstructed sample.
output logic recon_ready,
// Reconstructed sample Rx and its coordinate.
// Reconstructed sample Rx and its x coordinate.
input var logic [PIX_WIDTH-1:0] recon_sample,
input var logic [12:0] recon_x,
input var logic [12:0] recon_y
input var logic [12:0] recon_x
);
// Two line banks implement previous/current reconstructed rows. The active
@@ -105,8 +104,6 @@ module jls_neighbor_provider #(
// One outstanding pixel is held until its reconstructed sample returns when
// NEAR>0. The NEAR=0 path does not use this bubble because Rx == X.
logic waiting_reconstruct;
logic [12:0] outstanding_x;
logic [12:0] outstanding_y;
logic outstanding_row_last;
// Left reconstructed neighbor for non-left-edge pixels in the current row.
@@ -150,6 +147,10 @@ module jls_neighbor_provider #(
logic line_write_bank;
logic [12:0] line_write_addr;
logic [PIX_WIDTH-1:0] line_write_sample;
logic line_write_pending_valid;
logic line_write_pending_bank;
logic [12:0] line_write_pending_addr;
logic [PIX_WIDTH-1:0] line_write_pending_sample;
// Handshake terms.
logic neigh_slot_open;
@@ -161,7 +162,6 @@ module jls_neighbor_provider #(
logic recon_bypass_not_row_last;
logic recon_bypass_strip_ok;
logic recon_bypass_x_matches;
logic recon_bypass_y_matches;
logic same_row_recon_bypass_ready;
always_comb begin
@@ -369,20 +369,13 @@ module jls_neighbor_provider #(
end
end
always_comb begin
recon_bypass_y_matches = 1'b0;
if (pixel_y == recon_y) begin
recon_bypass_y_matches = 1'b1;
end
end
always_comb begin
// Diagnostic decode for the previous same-row bypass condition. The
// timing path now waits one clock after Rx writeback instead of using this
// condition in pixel_ready.
same_row_recon_bypass_ready = 1'b0;
if (accept_recon_write && recon_bypass_not_row_last && recon_bypass_strip_ok &&
recon_bypass_x_matches && recon_bypass_y_matches) begin
recon_bypass_x_matches) begin
same_row_recon_bypass_ready = 1'b1;
end
end
@@ -392,8 +385,6 @@ module jls_neighbor_provider #(
read_bank <= 1'b0;
top_row_active <= 1'b1;
waiting_reconstruct <= 1'b0;
outstanding_x <= 13'd0;
outstanding_y <= 13'd0;
outstanding_row_last <= 1'b0;
left_Ra <= {PIX_WIDTH{1'b0}};
left_edge_Rc <= {PIX_WIDTH{1'b0}};
@@ -408,7 +399,32 @@ module jls_neighbor_provider #(
Rb <= {PIX_WIDTH{1'b0}};
Rc <= {PIX_WIDTH{1'b0}};
Rd <= {PIX_WIDTH{1'b0}};
line_write_pending_valid <= 1'b0;
line_write_pending_bank <= 1'b0;
line_write_pending_addr <= 13'd0;
line_write_pending_sample <= {PIX_WIDTH{1'b0}};
end else begin
if (line_write_pending_valid) begin
case (line_write_pending_bank)
1'b0: begin
line_bank0[line_write_pending_addr] <= line_write_pending_sample;
end
default: begin
line_bank1[line_write_pending_addr] <= line_write_pending_sample;
end
endcase
end
if (line_write_valid) begin
line_write_pending_valid <= 1'b1;
line_write_pending_bank <= line_write_bank;
line_write_pending_addr <= line_write_addr;
line_write_pending_sample <= line_write_sample;
end else begin
line_write_pending_valid <= 1'b0;
end
if (neigh_valid && neigh_ready && !accept_pixel) begin
neigh_valid <= 1'b0;
end
@@ -425,8 +441,6 @@ module jls_neighbor_provider #(
Rc <= Rc_next;
Rd <= Rd_next;
waiting_reconstruct <= accept_pixel_needs_recon;
outstanding_x <= pixel_x;
outstanding_y <= pixel_y;
outstanding_row_last <= pixel_x_is_right_edge;
if (strip_first_pixel) begin
@@ -466,17 +480,6 @@ module jls_neighbor_provider #(
end
end
if (line_write_valid) begin
case (line_write_bank)
1'b0: begin
line_bank0[line_write_addr] <= line_write_sample;
end
default: begin
line_bank1[line_write_addr] <= line_write_sample;
end
endcase
end
end
end

View File

@@ -6,9 +6,7 @@
// Trace : docs/jls_traceability.md#jls-output-buffer
// Example : A byte event {start=1, byte=8'hFF} becomes ofifo_wdata=9'h1FF.
//
// Internal output buffer for the 9-bit output FIFO interface. The external
// ofifo_full/ofifo_alfull inputs are intentionally ignored by RTL behavior per
// the SRS; simulation reports an error if a write happens while ofifo_full=1.
// Internal output buffer for the 9-bit output FIFO interface.
`default_nettype none
@@ -54,13 +52,7 @@ module jls_output_buffer #(
output logic ofifo_wr,
// Output FIFO data. Bit 8 marks original-image start; bits 7:0 carry bytes.
output logic [8:0] ofifo_wdata,
// Reserved output FIFO full flag. RTL ignores this input for flow control.
input var logic ofifo_full,
// Reserved output FIFO almost-full flag. RTL ignores this input.
input var logic ofifo_alfull
output logic [8:0] ofifo_wdata
);
// Pointer width for the circular byte buffer.
@@ -97,10 +89,6 @@ module jls_output_buffer #(
// Packed byte event stored in the internal buffer.
logic [8:0] buffer_write_word;
// Reserved input observation signal keeps intent explicit without changing
// flow control behavior.
logic ofifo_alfull_ignored;
assign ofifo_wclk = clk;
always_comb begin
@@ -171,10 +159,6 @@ module jls_output_buffer #(
end
end
always_comb begin
ofifo_alfull_ignored = ofifo_alfull;
end
always_ff @(posedge clk) begin
if (rst) begin
write_ptr <= {PTR_WIDTH{1'b0}};

View File

@@ -92,7 +92,7 @@ module jls_predictor #(
logic [PIX_WIDTH:0] rc_ext;
logic [PIX_WIDTH:0] neighbor_min_ext;
logic [PIX_WIDTH:0] neighbor_max_ext;
logic [PIX_WIDTH:0] med_sum_ext;
logic [PIX_WIDTH-1:0] med_sum_ext;
logic [PIX_WIDTH-1:0] med_selected;
// Split comparison terms. This mirrors the standard if/else decision while

View File

@@ -4,13 +4,12 @@
// Table : Table C.1 valid preset parameters, Table C.2 RESET, Table C.3 defaults
// Pseudocode : Default threshold calculation with MAXVAL and NEAR
// Trace : docs/jls_traceability.md#jls-preset-defaults
// Example : PIX_WIDTH=8, NEAR=0 gives MAXVAL=255, T1=3, T2=7, T3=21.
// Example : PIX_WIDTH=16 and NEAR=64 gives T1/T2/T3 = 210/387/724.
//
// JPEG-LS default preset coding parameter helper. This version follows the
// full CharLS/ISO formula and supports NEAR up to min(255, MAXVAL/2). The
// work is strip-level control, not per-pixel, so one combinational divide is
// acceptable here and keeps the pixel pipeline independent of the wider NEAR
// range.
// JPEG-LS default preset coding parameter helper. The project NEAR controller
// only emits a discrete ladder {0,1,2,4,8,16,32,64,127,255}. Direct table
// lookup keeps strip-start timing shallow and avoids the long threshold
// arithmetic carry chains from the generic Annex C.2.4.1.1 formula.
`default_nettype none
@@ -18,7 +17,7 @@ module jls_preset_defaults #(
// Compile-time grayscale sample precision. Legal values: 8, 10, 12, 14, 16.
parameter int PIX_WIDTH = 16
) (
// Requested NEAR value. Values above min(255, MAXVAL/2) are clamped.
// Requested NEAR value.
input var logic [7:0] near,
// JPEG-LS LSE MAXVAL preset coding parameter.
@@ -37,139 +36,338 @@ module jls_preset_defaults #(
output logic [15:0] preset_reset
);
localparam int DEFAULT_RESET_VALUE = 64;
localparam int BASIC_T1 = 3;
localparam int BASIC_T2 = 7;
localparam int BASIC_T3 = 21;
integer maximum_sample_value_int;
integer maximum_near_int;
integer near_clamped_int;
integer factor_int;
integer threshold1_candidate;
integer threshold2_candidate;
integer threshold3_candidate;
integer threshold1_int;
integer threshold2_int;
integer threshold3_int;
localparam logic [15:0] DEFAULT_RESET_VALUE = 16'd64;
always_comb begin
maximum_sample_value_int = 65535;
preset_maxval = 16'd65535;
preset_t1 = 16'd18;
preset_t2 = 16'd67;
preset_t3 = 16'd276;
preset_reset = DEFAULT_RESET_VALUE;
case (PIX_WIDTH)
8: begin
maximum_sample_value_int = 255;
preset_maxval = 16'd255;
case (near)
8'd0: begin
preset_t1 = 16'd3;
preset_t2 = 16'd7;
preset_t3 = 16'd21;
end
8'd1: begin
preset_t1 = 16'd6;
preset_t2 = 16'd12;
preset_t3 = 16'd28;
end
8'd2: begin
preset_t1 = 16'd9;
preset_t2 = 16'd17;
preset_t3 = 16'd35;
end
8'd4: begin
preset_t1 = 16'd15;
preset_t2 = 16'd27;
preset_t3 = 16'd49;
end
8'd8: begin
preset_t1 = 16'd27;
preset_t2 = 16'd47;
preset_t3 = 16'd77;
end
8'd16: begin
preset_t1 = 16'd51;
preset_t2 = 16'd87;
preset_t3 = 16'd133;
end
8'd31: begin
preset_t1 = 16'd96;
preset_t2 = 16'd162;
preset_t3 = 16'd238;
end
8'd32: begin
preset_t1 = 16'd99;
preset_t2 = 16'd167;
preset_t3 = 16'd245;
end
8'd63: begin
preset_t1 = 16'd192;
preset_t2 = 16'd255;
preset_t3 = 16'd255;
end
default: begin
preset_t1 = 16'd255;
preset_t2 = 16'd255;
preset_t3 = 16'd255;
end
endcase
end
10: begin
maximum_sample_value_int = 1023;
preset_maxval = 16'd1023;
case (near)
8'd0: begin
preset_t1 = 16'd6;
preset_t2 = 16'd19;
preset_t3 = 16'd72;
end
8'd1: begin
preset_t1 = 16'd9;
preset_t2 = 16'd24;
preset_t3 = 16'd79;
end
8'd2: begin
preset_t1 = 16'd12;
preset_t2 = 16'd29;
preset_t3 = 16'd86;
end
8'd4: begin
preset_t1 = 16'd18;
preset_t2 = 16'd39;
preset_t3 = 16'd100;
end
8'd8: begin
preset_t1 = 16'd30;
preset_t2 = 16'd59;
preset_t3 = 16'd128;
end
8'd16: begin
preset_t1 = 16'd54;
preset_t2 = 16'd99;
preset_t3 = 16'd184;
end
8'd31: begin
preset_t1 = 16'd99;
preset_t2 = 16'd174;
preset_t3 = 16'd289;
end
8'd32: begin
preset_t1 = 16'd102;
preset_t2 = 16'd179;
preset_t3 = 16'd296;
end
8'd63: begin
preset_t1 = 16'd195;
preset_t2 = 16'd334;
preset_t3 = 16'd513;
end
8'd64: begin
preset_t1 = 16'd198;
preset_t2 = 16'd339;
preset_t3 = 16'd520;
end
8'd127: begin
preset_t1 = 16'd387;
preset_t2 = 16'd654;
preset_t3 = 16'd961;
end
default: begin
preset_t1 = 16'd771;
preset_t2 = 16'd1023;
preset_t3 = 16'd1023;
end
endcase
end
12: begin
maximum_sample_value_int = 4095;
preset_maxval = 16'd4095;
case (near)
8'd0: begin
preset_t1 = 16'd18;
preset_t2 = 16'd67;
preset_t3 = 16'd276;
end
8'd1: begin
preset_t1 = 16'd21;
preset_t2 = 16'd72;
preset_t3 = 16'd283;
end
8'd2: begin
preset_t1 = 16'd24;
preset_t2 = 16'd77;
preset_t3 = 16'd290;
end
8'd4: begin
preset_t1 = 16'd30;
preset_t2 = 16'd87;
preset_t3 = 16'd304;
end
8'd8: begin
preset_t1 = 16'd42;
preset_t2 = 16'd107;
preset_t3 = 16'd332;
end
8'd16: begin
preset_t1 = 16'd66;
preset_t2 = 16'd147;
preset_t3 = 16'd388;
end
8'd31: begin
preset_t1 = 16'd111;
preset_t2 = 16'd222;
preset_t3 = 16'd493;
end
8'd32: begin
preset_t1 = 16'd114;
preset_t2 = 16'd227;
preset_t3 = 16'd500;
end
8'd63: begin
preset_t1 = 16'd207;
preset_t2 = 16'd382;
preset_t3 = 16'd717;
end
8'd64: begin
preset_t1 = 16'd210;
preset_t2 = 16'd387;
preset_t3 = 16'd724;
end
8'd127: begin
preset_t1 = 16'd399;
preset_t2 = 16'd702;
preset_t3 = 16'd1165;
end
default: begin
preset_t1 = 16'd783;
preset_t2 = 16'd1342;
preset_t3 = 16'd2061;
end
endcase
end
14: begin
maximum_sample_value_int = 16383;
preset_maxval = 16'd16383;
case (near)
8'd0: begin
preset_t1 = 16'd18;
preset_t2 = 16'd67;
preset_t3 = 16'd276;
end
8'd1: begin
preset_t1 = 16'd21;
preset_t2 = 16'd72;
preset_t3 = 16'd283;
end
8'd2: begin
preset_t1 = 16'd24;
preset_t2 = 16'd77;
preset_t3 = 16'd290;
end
8'd4: begin
preset_t1 = 16'd30;
preset_t2 = 16'd87;
preset_t3 = 16'd304;
end
8'd8: begin
preset_t1 = 16'd42;
preset_t2 = 16'd107;
preset_t3 = 16'd332;
end
8'd16: begin
preset_t1 = 16'd66;
preset_t2 = 16'd147;
preset_t3 = 16'd388;
end
8'd31: begin
preset_t1 = 16'd111;
preset_t2 = 16'd222;
preset_t3 = 16'd493;
end
8'd32: begin
preset_t1 = 16'd114;
preset_t2 = 16'd227;
preset_t3 = 16'd500;
end
8'd63: begin
preset_t1 = 16'd207;
preset_t2 = 16'd382;
preset_t3 = 16'd717;
end
8'd64: begin
preset_t1 = 16'd210;
preset_t2 = 16'd387;
preset_t3 = 16'd724;
end
8'd127: begin
preset_t1 = 16'd399;
preset_t2 = 16'd702;
preset_t3 = 16'd1165;
end
default: begin
preset_t1 = 16'd783;
preset_t2 = 16'd1342;
preset_t3 = 16'd2061;
end
endcase
end
default: begin
maximum_sample_value_int = 65535;
preset_maxval = 16'd65535;
case (near)
8'd0: begin
preset_t1 = 16'd18;
preset_t2 = 16'd67;
preset_t3 = 16'd276;
end
8'd1: begin
preset_t1 = 16'd21;
preset_t2 = 16'd72;
preset_t3 = 16'd283;
end
8'd2: begin
preset_t1 = 16'd24;
preset_t2 = 16'd77;
preset_t3 = 16'd290;
end
8'd4: begin
preset_t1 = 16'd30;
preset_t2 = 16'd87;
preset_t3 = 16'd304;
end
8'd8: begin
preset_t1 = 16'd42;
preset_t2 = 16'd107;
preset_t3 = 16'd332;
end
8'd16: begin
preset_t1 = 16'd66;
preset_t2 = 16'd147;
preset_t3 = 16'd388;
end
8'd31: begin
preset_t1 = 16'd111;
preset_t2 = 16'd222;
preset_t3 = 16'd493;
end
8'd32: begin
preset_t1 = 16'd114;
preset_t2 = 16'd227;
preset_t3 = 16'd500;
end
8'd63: begin
preset_t1 = 16'd207;
preset_t2 = 16'd382;
preset_t3 = 16'd717;
end
8'd64: begin
preset_t1 = 16'd210;
preset_t2 = 16'd387;
preset_t3 = 16'd724;
end
8'd127: begin
preset_t1 = 16'd399;
preset_t2 = 16'd702;
preset_t3 = 16'd1165;
end
default: begin
preset_t1 = 16'd783;
preset_t2 = 16'd1342;
preset_t3 = 16'd2061;
end
endcase
end
endcase
end
always_comb begin
maximum_near_int = maximum_sample_value_int / 2;
if (maximum_near_int > 255) begin
maximum_near_int = 255;
end
end
always_comb begin
near_clamped_int = near;
if (near_clamped_int > maximum_near_int) begin
near_clamped_int = maximum_near_int;
end
end
always_comb begin
factor_int = 1;
if (maximum_sample_value_int >= 128) begin
factor_int = maximum_sample_value_int;
if (factor_int > 4095) begin
factor_int = 4095;
end
factor_int = (factor_int + 128) / 256;
threshold1_candidate = (factor_int * (BASIC_T1 - 2)) + 2 + (3 * near_clamped_int);
if ((threshold1_candidate > maximum_sample_value_int) ||
(threshold1_candidate < (near_clamped_int + 1))) begin
threshold1_int = near_clamped_int + 1;
end else begin
threshold1_int = threshold1_candidate;
end
threshold2_candidate = (factor_int * (BASIC_T2 - 3)) + 3 + (5 * near_clamped_int);
if ((threshold2_candidate > maximum_sample_value_int) ||
(threshold2_candidate < threshold1_int)) begin
threshold2_int = threshold1_int;
end else begin
threshold2_int = threshold2_candidate;
end
threshold3_candidate = (factor_int * (BASIC_T3 - 4)) + 4 + (7 * near_clamped_int);
if ((threshold3_candidate > maximum_sample_value_int) ||
(threshold3_candidate < threshold2_int)) begin
threshold3_int = threshold2_int;
end else begin
threshold3_int = threshold3_candidate;
end
end else begin
factor_int = 256 / (maximum_sample_value_int + 1);
threshold1_candidate = (BASIC_T1 / factor_int) + (3 * near_clamped_int);
if (threshold1_candidate < 2) begin
threshold1_candidate = 2;
end
if ((threshold1_candidate > maximum_sample_value_int) ||
(threshold1_candidate < (near_clamped_int + 1))) begin
threshold1_int = near_clamped_int + 1;
end else begin
threshold1_int = threshold1_candidate;
end
threshold2_candidate = (BASIC_T2 / factor_int) + (5 * near_clamped_int);
if (threshold2_candidate < 3) begin
threshold2_candidate = 3;
end
if ((threshold2_candidate > maximum_sample_value_int) ||
(threshold2_candidate < threshold1_int)) begin
threshold2_int = threshold1_int;
end else begin
threshold2_int = threshold2_candidate;
end
threshold3_candidate = (BASIC_T3 / factor_int) + (7 * near_clamped_int);
if (threshold3_candidate < 4) begin
threshold3_candidate = 4;
end
if ((threshold3_candidate > maximum_sample_value_int) ||
(threshold3_candidate < threshold2_int)) begin
threshold3_int = threshold2_int;
end else begin
threshold3_int = threshold3_candidate;
end
end
end
always_comb begin
preset_maxval = maximum_sample_value_int[15:0];
preset_t1 = threshold1_int[15:0];
preset_t2 = threshold2_int[15:0];
preset_t3 = threshold3_int[15:0];
preset_reset = DEFAULT_RESET_VALUE[15:0];
end
endmodule
`default_nettype wire

View File

@@ -58,6 +58,7 @@ module jls_regular_error_quantizer #(
// Coding parameters for the current strip frame.
input var logic [16:0] RANGE,
input var logic [4:0] qbpp,
input var logic [16:0] RANGE_SCALE,
input var logic [6:0] LIMIT,
input var logic [7:0] NEAR,
@@ -121,7 +122,7 @@ module jls_regular_error_quantizer #(
// One-hot state decode keeps per-stage enables shallow. This is important
// when explicit timing-boundary registers below are preserved for 250 MHz.
(* fsm_encoding = "one_hot" *) quant_state_e state;
(* fsm_encoding = "one_hot", fsm_safe_state = "reset_state" *) quant_state_e state;
// Latched event fields.
logic [PIX_WIDTH-1:0] sample_latched;
@@ -138,6 +139,7 @@ module jls_regular_error_quantizer #(
logic signed [8:0] C_latched;
logic [15:0] N_latched;
logic [16:0] RANGE_latched;
logic [16:0] RANGE_SCALE_latched;
logic [4:0] qbpp_latched;
logic [6:0] LIMIT_latched;
logic [7:0] NEAR_latched;
@@ -197,7 +199,6 @@ module jls_regular_error_quantizer #(
logic signed [40:0] reconstruction_base_latched;
logic signed [40:0] reconstruction_sum;
logic signed [40:0] reconstruction_sum_latched;
logic signed [40:0] range_scaled;
logic signed [40:0] range_scaled_latched;
logic signed [40:0] reconstruction_fixed;
logic signed [40:0] reconstruction_fixed_latched;
@@ -224,15 +225,6 @@ module jls_regular_error_quantizer #(
.product_o(dequantized_error)
);
jls_near_scale_mul #(
.INPUT_WIDTH(18),
.OUTPUT_WIDTH(41)
) regular_recon_range_mul_i (
.multiplicand_i($signed({1'b0, RANGE_latched})),
.near_scale_i(near_scale_latched[8:0]),
.product_o(range_scaled)
);
jls_near_reciprocal_magic_lut regular_err_recip_magic_lut_i (
.near_i(NEAR_latched),
.reciprocal_magic_o(reciprocal_magic_next)
@@ -412,6 +404,7 @@ module jls_regular_error_quantizer #(
C_latched <= 9'sd0;
N_latched <= 16'd0;
RANGE_latched <= 17'd0;
RANGE_SCALE_latched <= 17'd0;
qbpp_latched <= 5'd0;
LIMIT_latched <= 7'd0;
NEAR_latched <= 8'd0;
@@ -478,6 +471,7 @@ module jls_regular_error_quantizer #(
C_latched <= corrected_C;
N_latched <= corrected_N;
RANGE_latched <= RANGE;
RANGE_SCALE_latched <= RANGE_SCALE;
qbpp_latched <= qbpp;
LIMIT_latched <= LIMIT;
NEAR_latched <= NEAR;
@@ -601,7 +595,7 @@ module jls_regular_error_quantizer #(
// NEAR-to-Rx combinational depth at the 250 MHz target.
dequantized_error_latched <= dequantized_error;
reconstruction_base_latched <= reconstruction_base;
range_scaled_latched <= range_scaled;
range_scaled_latched <= $signed({24'd0, RANGE_SCALE_latched});
maxval_ext_latched <= maxval_ext;
near_ext_latched <= near_ext;
state <= STATE_RECON_SUM;

View File

@@ -128,7 +128,7 @@ module jls_run_mode #(
STATE_ERRVAL_PREP = 5'd22
} run_state_e;
run_state_e state;
(* fsm_safe_state = "reset_state" *) run_state_e state;
run_state_e state_after_run_code;
// Standard RUNindex and run-interruption contexts. Context 0 is RItype=0,
@@ -238,7 +238,7 @@ module jls_run_mode #(
logic signed [32:0] modulo_Errval_after_add_latched;
logic signed [32:0] modulo_Errval;
logic signed [32:0] modulo_Errval_latched;
logic [32:0] abs_Errval_ext;
logic [30:0] abs_Errval_ext;
logic signed [32:0] sign_restored_Errval;
// Pipeline register between modulo/sign restoration and the run-interruption
// odd-scale reconstruction multiply.
@@ -298,7 +298,7 @@ module jls_run_mode #(
logic [4:0] k_latched;
logic [16:0] two_Nn_ext;
logic run_map_next;
logic [32:0] MErrval_ext;
logic [31:0] MErrval_ext;
logic [31:0] MErrval_latched;
logic [31:0] A_update_delta;
logic [31:0] A_update_delta_latched;
@@ -622,7 +622,7 @@ module jls_run_mode #(
end
always_comb begin
abs_Errval_ext = modulo_Errval_latched[32:0];
abs_Errval_ext = modulo_Errval_latched[30:0];
if (modulo_Errval_latched < 33'sd0) begin
abs_Errval_ext = -modulo_Errval_latched;
end
@@ -809,8 +809,8 @@ module jls_run_mode #(
end
always_comb begin
MErrval_ext = {abs_Errval_ext[31:0], 1'b0} - {32'd0, RItype_latched} -
{32'd0, run_map_next};
MErrval_ext = {abs_Errval_ext, 1'b0} - {31'd0, RItype_latched} -
{31'd0, run_map_next};
end
always_comb begin
@@ -1133,7 +1133,23 @@ module jls_run_mode #(
STATE_RUN_CODE_WAIT: begin
if (!run_code_valid) begin
state <= state_after_run_code;
case (state_after_run_code)
STATE_DONE: begin
state <= STATE_DONE;
end
STATE_ERRVAL_PREP: begin
state <= STATE_ERRVAL_PREP;
end
STATE_DIV_MUL: begin
state <= STATE_DIV_MUL;
end
default: begin
state <= STATE_IDLE;
end
endcase
end
end

View File

@@ -20,7 +20,7 @@ module jls_scan_ctrl #(
parameter int PIX_WIDTH = 16,
// Number of original-image rows in one standalone JPEG-LS strip frame.
parameter int SCAN_ROWS = 16
parameter int SCAN_ROWS = 64
) (
// Main 250 MHz clock.
input var logic clk,
@@ -256,7 +256,11 @@ module jls_scan_ctrl #(
always_comb begin
strip_start_valid = 1'b0;
if (slot_valid && slot_strip_first_pixel && finish_path_ready && enc_pixel_ready) begin
// Strip-start command may launch one cycle earlier than the first pixel
// forward. This cuts the downstream enc_pixel_ready chain out of the
// header/context start path while the slot still holds the first pixel
// until enc_pixel_ready eventually goes high.
if (slot_valid && slot_strip_first_pixel && finish_path_ready) begin
strip_start_valid = 1'b1;
end
end

View File

@@ -28,7 +28,7 @@ module jpeg_ls_encoder_top #(
parameter int MAX_PIC_ROW = 4096,
// Number of original-image rows in one standalone JPEG-LS strip frame.
parameter int SCAN_ROWS = 16,
parameter int SCAN_ROWS = 64,
// Maximum dynamic NEAR value.
parameter int MAX_NEAR = 255,
@@ -150,6 +150,12 @@ module jpeg_ls_encoder_top #(
logic strip_finish_accepted;
logic [7:0] active_strip_near;
logic [31:0] active_strip_pixel_count;
logic start_stage_valid;
logic [12:0] start_stage_strip_width;
logic [12:0] start_stage_strip_height;
logic start_stage_original_image_first_strip;
logic [7:0] start_stage_near;
logic start_stage_lossless_fast;
// Preset and coding parameters for strip-start header and active pipeline.
logic [15:0] start_preset_maxval;
@@ -158,8 +164,17 @@ module jpeg_ls_encoder_top #(
logic [15:0] start_preset_t3;
logic [15:0] start_preset_reset;
logic [16:0] start_RANGE;
(* keep = "true" *) logic [16:0] start_RANGE_SCALE_unused;
logic [4:0] start_qbpp;
logic [6:0] start_LIMIT;
logic [15:0] start_stage_preset_maxval;
logic [15:0] start_stage_preset_t1;
logic [15:0] start_stage_preset_t2;
logic [15:0] start_stage_preset_t3;
logic [15:0] start_stage_preset_reset;
logic [16:0] start_stage_RANGE;
logic [4:0] start_stage_qbpp;
logic [6:0] start_stage_LIMIT;
logic [15:0] active_preset_maxval;
logic [15:0] active_preset_t1;
logic [15:0] active_preset_t2;
@@ -167,6 +182,7 @@ module jpeg_ls_encoder_top #(
logic [15:0] active_preset_reset;
logic [16:0] active_RANGE;
logic [4:0] active_qbpp;
logic [16:0] active_RANGE_SCALE;
logic [6:0] active_LIMIT;
// Header writer and output byte arbitration.
@@ -188,6 +204,7 @@ module jpeg_ls_encoder_top #(
logic [7:0] arb_byte_data;
logic arb_original_image_start;
logic arb_byte_accepted;
(* keep = "true" *) logic reserved_ofifo_flags_observed;
logic output_pause_req;
logic [$clog2(OUT_BUF_BYTES + 1)-1:0] output_buffer_level;
@@ -207,7 +224,6 @@ module jpeg_ls_encoder_top #(
logic recon_ready_from_neighbor;
logic [PIX_WIDTH-1:0] recon_sample_to_neighbor;
logic [12:0] recon_x_to_neighbor;
logic [12:0] recon_y_to_neighbor;
logic scan_strip_lossless_fast;
logic active_strip_lossless_fast;
logic neighbor_lossless_fast;
@@ -428,7 +444,6 @@ module jpeg_ls_encoder_top #(
logic regular_recon_ready;
logic [PIX_WIDTH-1:0] regular_recon_sample_latched;
logic [12:0] regular_recon_x_latched;
logic [12:0] regular_recon_y_latched;
// Reconstructed-sample feedback queue. JPEG-LS Annex A.4/A.5 requires the
// next neighborhood to use encoder-side Rx history. This two-entry queue is
// a 250 MHz timing boundary between regular/run reconstruction sources and
@@ -444,13 +459,10 @@ module jpeg_ls_encoder_top #(
logic recon_feedback_load_next;
logic [PIX_WIDTH-1:0] recon_feedback_source_sample;
logic [12:0] recon_feedback_source_x;
logic [12:0] recon_feedback_source_y;
logic [PIX_WIDTH-1:0] recon_feedback_sample;
logic [12:0] recon_feedback_x;
logic [12:0] recon_feedback_y;
logic [PIX_WIDTH-1:0] recon_feedback_next_sample;
logic [12:0] recon_feedback_next_x;
logic [12:0] recon_feedback_next_y;
logic code_valid;
logic code_ready;
logic [MAX_CODE_BITS-1:0] code_bits;
@@ -472,12 +484,13 @@ module jpeg_ls_encoder_top #(
CLOSE_EOI_WAIT = 3'd4
} close_state_e;
close_state_e close_state;
(* fsm_safe_state = "reset_state", fsm_encoding = "one_hot" *) close_state_e close_state;
logic payload_flush_valid;
logic payload_flush_ready;
logic payload_flush_done;
logic [31:0] strip_output_byte_count;
logic [31:0] strip_output_byte_count_after_accept;
logic start_stage_capture;
always_comb begin
strip_start_accepted = 1'b0;
@@ -495,10 +508,19 @@ module jpeg_ls_encoder_top #(
always_comb begin
scan_strip_start_ready = 1'b0;
if (header_strip_start_ready && context_init_ready &&
run_strip_init_ready_q && !strip_open_active && close_state == CLOSE_IDLE &&
if (!strip_open_active && close_state == CLOSE_IDLE &&
!near_update_pending && !near_update_busy) begin
scan_strip_start_ready = 1'b1;
if (start_stage_valid) begin
if (header_strip_start_ready && context_init_ready &&
run_strip_init_ready_q) begin
scan_strip_start_ready = 1'b1;
end
end else if (!scan_strip_start_valid) begin
// Let the first strip pixel enter the scan-control holding slot. The
// next cycle captures NEAR/preset/coding params into start-stage
// registers, and only then releases strip_start_ready for launch.
scan_strip_start_ready = 1'b1;
end
end
end
@@ -506,6 +528,15 @@ module jpeg_ls_encoder_top #(
scan_strip_finish_ready = 1'b1;
end
always_comb begin
start_stage_capture = 1'b0;
if (scan_strip_start_valid && !start_stage_valid &&
!strip_open_active && close_state == CLOSE_IDLE &&
!near_update_pending && !near_update_busy) begin
start_stage_capture = 1'b1;
end
end
always_comb begin
// Fan out strip-start only after all start-side consumers are ready; this
// keeps header/context/run initialization atomic across strip boundaries.
@@ -573,18 +604,15 @@ module jpeg_ls_encoder_top #(
recon_feedback_source_valid = 1'b0;
recon_feedback_source_sample = regular_recon_sample_latched;
recon_feedback_source_x = regular_recon_x_latched;
recon_feedback_source_y = regular_recon_y_latched;
if (run_interruption_recon_valid) begin
recon_feedback_source_valid = 1'b1;
recon_feedback_source_sample = run_interruption_recon_sample;
recon_feedback_source_x = run_interruption_recon_x;
recon_feedback_source_y = run_interruption_recon_y;
end
if (mode_run_recon_valid && (!mode_run_segment_valid || mode_run_segment_ready)) begin
recon_feedback_source_valid = 1'b1;
recon_feedback_source_sample = mode_run_recon_sample;
recon_feedback_source_x = mode_run_recon_x;
recon_feedback_source_y = mode_run_recon_y;
end else if (regular_recon_valid && !run_interruption_recon_valid) begin
recon_feedback_source_valid = 1'b1;
end
@@ -629,7 +657,6 @@ module jpeg_ls_encoder_top #(
always_comb begin
recon_sample_to_neighbor = recon_feedback_sample;
recon_x_to_neighbor = recon_feedback_x;
recon_y_to_neighbor = recon_feedback_y;
end
always_comb begin
@@ -666,17 +693,14 @@ module jpeg_ls_encoder_top #(
recon_feedback_next_valid <= 1'b0;
recon_feedback_sample <= {PIX_WIDTH{1'b0}};
recon_feedback_x <= 13'd0;
recon_feedback_y <= 13'd0;
recon_feedback_next_sample <= {PIX_WIDTH{1'b0}};
recon_feedback_next_x <= 13'd0;
recon_feedback_next_y <= 13'd0;
end else begin
if (recon_feedback_to_neighbor) begin
if (recon_feedback_next_valid) begin
recon_feedback_valid <= 1'b1;
recon_feedback_sample <= recon_feedback_next_sample;
recon_feedback_x <= recon_feedback_next_x;
recon_feedback_y <= recon_feedback_next_y;
recon_feedback_next_valid <= 1'b0;
end else begin
recon_feedback_valid <= 1'b0;
@@ -687,14 +711,12 @@ module jpeg_ls_encoder_top #(
recon_feedback_valid <= 1'b1;
recon_feedback_sample <= recon_feedback_source_sample;
recon_feedback_x <= recon_feedback_source_x;
recon_feedback_y <= recon_feedback_source_y;
end
if (recon_feedback_load_next) begin
recon_feedback_next_valid <= 1'b1;
recon_feedback_next_sample <= recon_feedback_source_sample;
recon_feedback_next_x <= recon_feedback_source_x;
recon_feedback_next_y <= recon_feedback_source_y;
end
end
end
@@ -722,11 +744,11 @@ module jpeg_ls_encoder_top #(
run_mode_NEAR = active_strip_near;
run_mode_RESET = active_preset_reset;
if (run_strip_init_valid) begin
run_mode_RANGE = start_RANGE;
run_mode_qbpp = start_qbpp;
run_mode_LIMIT = start_LIMIT;
run_mode_NEAR = scan_strip_near;
run_mode_RESET = start_preset_reset;
run_mode_RANGE = start_stage_RANGE;
run_mode_qbpp = start_stage_qbpp;
run_mode_LIMIT = start_stage_LIMIT;
run_mode_NEAR = start_stage_near;
run_mode_RESET = start_stage_preset_reset;
end
end
@@ -1000,6 +1022,10 @@ module jpeg_ls_encoder_top #(
.near_image_ratio(near_image_ratio)
);
always_comb begin
reserved_ofifo_flags_observed = ofifo_full | ofifo_alfull;
end
always_comb begin
input_pixel_ready = scan_pixel_ready;
end
@@ -1021,6 +1047,7 @@ module jpeg_ls_encoder_top #(
.NEAR(scan_strip_near),
.RANGE(start_RANGE),
.qbpp(start_qbpp),
.RANGE_SCALE(start_RANGE_SCALE_unused),
.LIMIT(start_LIMIT)
);
@@ -1041,6 +1068,7 @@ module jpeg_ls_encoder_top #(
.NEAR(active_strip_near),
.RANGE(active_RANGE),
.qbpp(active_qbpp),
.RANGE_SCALE(active_RANGE_SCALE),
.LIMIT(active_LIMIT)
);
@@ -1051,15 +1079,15 @@ module jpeg_ls_encoder_top #(
.rst(rst),
.strip_start_valid(header_strip_start_valid),
.strip_start_ready(header_strip_start_ready),
.original_image_first_strip(scan_original_image_first_strip),
.strip_width(scan_strip_width),
.strip_height(scan_strip_height),
.near(scan_strip_near),
.preset_maxval(start_preset_maxval),
.preset_t1(start_preset_t1),
.preset_t2(start_preset_t2),
.preset_t3(start_preset_t3),
.preset_reset(start_preset_reset),
.original_image_first_strip(start_stage_original_image_first_strip),
.strip_width(start_stage_strip_width),
.strip_height(start_stage_strip_height),
.near(start_stage_near),
.preset_maxval(start_stage_preset_maxval),
.preset_t1(start_stage_preset_t1),
.preset_t2(start_stage_preset_t2),
.preset_t3(start_stage_preset_t3),
.preset_reset(start_stage_preset_reset),
.strip_finish_valid(header_strip_finish_valid),
.strip_finish_ready(header_strip_finish_ready),
.byte_valid(header_byte_valid),
@@ -1099,8 +1127,7 @@ module jpeg_ls_encoder_top #(
.recon_valid(recon_valid_to_neighbor),
.recon_ready(recon_ready_from_neighbor),
.recon_sample(recon_sample_to_neighbor),
.recon_x(recon_x_to_neighbor),
.recon_y(recon_y_to_neighbor)
.recon_x(recon_x_to_neighbor)
);
jls_mode_router #(
@@ -1230,7 +1257,7 @@ module jpeg_ls_encoder_top #(
.rst(rst),
.init_valid(context_init_valid),
.init_ready(context_init_ready),
.init_RANGE(start_RANGE),
.init_RANGE(start_stage_RANGE),
.init_busy(context_init_busy),
.init_done(context_init_done),
.context_valid(context_valid),
@@ -1327,6 +1354,7 @@ module jpeg_ls_encoder_top #(
.corrected_N(corrected_N),
.RANGE(active_RANGE),
.qbpp(active_qbpp),
.RANGE_SCALE(active_RANGE_SCALE),
.LIMIT(active_LIMIT),
.NEAR(active_strip_near),
.err_valid(regular_err_valid),
@@ -1512,9 +1540,7 @@ module jpeg_ls_encoder_top #(
.buffer_level(output_buffer_level),
.ofifo_wclk(ofifo_wclk),
.ofifo_wr(ofifo_wr),
.ofifo_wdata(ofifo_wdata),
.ofifo_full(ofifo_full),
.ofifo_alfull(ofifo_alfull)
.ofifo_wdata(ofifo_wdata)
);
always_ff @(posedge clk) begin
@@ -1523,6 +1549,20 @@ module jpeg_ls_encoder_top #(
active_strip_near <= 8'd0;
active_strip_lossless_fast <= 1'b1;
active_strip_pixel_count <= 32'd0;
start_stage_valid <= 1'b0;
start_stage_strip_width <= 13'd0;
start_stage_strip_height <= 13'd0;
start_stage_original_image_first_strip <= 1'b0;
start_stage_near <= 8'd0;
start_stage_lossless_fast <= 1'b1;
start_stage_preset_maxval <= 16'd0;
start_stage_preset_t1 <= 16'd0;
start_stage_preset_t2 <= 16'd0;
start_stage_preset_t3 <= 16'd0;
start_stage_preset_reset <= 16'd0;
start_stage_RANGE <= 17'd0;
start_stage_qbpp <= 5'd0;
start_stage_LIMIT <= 7'd0;
near_update_pending <= 1'b0;
near_strip_pixel_count_latched <= 32'd0;
near_strip_output_bytes_latched <= 32'd0;
@@ -1532,7 +1572,6 @@ module jpeg_ls_encoder_top #(
regular_recon_valid <= 1'b0;
regular_recon_sample_latched <= {PIX_WIDTH{1'b0}};
regular_recon_x_latched <= 13'd0;
regular_recon_y_latched <= 13'd0;
run_core_done_pending <= 1'b0;
run_core_last_pending <= 1'b0;
run_golomb_busy <= 1'b0;
@@ -1557,7 +1596,6 @@ module jpeg_ls_encoder_top #(
regular_recon_valid <= 1'b1;
regular_recon_sample_latched <= regular_reconstructed_sample;
regular_recon_x_latched <= regular_err_x;
regular_recon_y_latched <= regular_err_y;
end
if (regular_recon_valid && regular_recon_ready) begin
@@ -1614,10 +1652,28 @@ module jpeg_ls_encoder_top #(
end
endcase
if (start_stage_capture) begin
start_stage_valid <= 1'b1;
start_stage_strip_width <= scan_strip_width;
start_stage_strip_height <= scan_strip_height;
start_stage_original_image_first_strip <= scan_original_image_first_strip;
start_stage_near <= scan_strip_near;
start_stage_lossless_fast <= scan_strip_lossless_fast;
start_stage_preset_maxval <= start_preset_maxval;
start_stage_preset_t1 <= start_preset_t1;
start_stage_preset_t2 <= start_preset_t2;
start_stage_preset_t3 <= start_preset_t3;
start_stage_preset_reset <= start_preset_reset;
start_stage_RANGE <= start_RANGE;
start_stage_qbpp <= start_qbpp;
start_stage_LIMIT <= start_LIMIT;
end
if (strip_start_accepted) begin
strip_open_active <= 1'b1;
active_strip_near <= scan_strip_near;
active_strip_lossless_fast <= scan_strip_lossless_fast;
active_strip_near <= start_stage_near;
active_strip_lossless_fast <= start_stage_lossless_fast;
start_stage_valid <= 1'b0;
strip_output_byte_count <= 32'd0;
end else begin
strip_output_byte_count <= strip_output_byte_count_after_accept;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 B

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 768 B

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 768 B

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 KiB

After

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 497 KiB

After

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 497 KiB

After

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 KiB

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 987 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 959 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 KiB

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 KiB

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 987 B

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -49,7 +49,7 @@ python tools/jls_compat/reference_decode_compare.py path/to/output.jls
Run smoke decode for a concatenated strip-frame stream:
```powershell
python tools/jls_compat/reference_decode_compare.py path/to/output_stream.jls --split-frames --expected-frames 16
python tools/jls_compat/reference_decode_compare.py path/to/output_stream.jls --split-frames --expected-frames 4
```
Run mature regression with libjpeg required: