Skip to content

Commit a97dfb1

Browse files
authored
Merge pull request #254 from brilliantlabsAR/jpeg-merging
JPEG optimisations
2 parents 1271c82 + 9376cb4 commit a97dfb1

18 files changed

+23805
-25321
lines changed

source/fpga/fpga_application.h

+23,406-24,944
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Authored by: Robert Metchev / Chips & Scripts (rmetchev@ieee.org)
3+
*
4+
* CERN Open Hardware Licence Version 2 - Permissive
5+
*
6+
* Copyright (C) 2024 Robert Metchev
7+
*/
8+
module bit_pack (
9+
//packed code+coeff
10+
input logic [63:0] in_data,
11+
input logic [6:0] in_nbits,
12+
input logic in_tlast,
13+
input logic in_valid,
14+
output logic in_hold,
15+
16+
output logic [31:0] out_data,
17+
output logic [2:0] out_nbytes,
18+
output logic out_tlast,
19+
output logic out_valid,
20+
input logic out_hold,
21+
22+
input logic clk,
23+
input logic resetn
24+
);
25+
26+
// 1.) 64-bit to 32-bit align: There will be extremely rarely more than 32 bits.
27+
// Stall during 1st 32 bits.
28+
logic [31:0] in32_data;
29+
logic [5:0] in32_nbits;
30+
logic in32_tlast;
31+
logic in32_valid;
32+
logic in32_hold;
33+
logic long_in;
34+
35+
always @(posedge clk)
36+
if (!resetn) begin
37+
in32_valid <= 0;
38+
long_in <= 0;
39+
end
40+
else if (~(in32_hold & in32_valid)) begin
41+
in32_valid <= in_valid;
42+
43+
if (long_in)
44+
long_in <= 0;
45+
else if (in_valid & in_nbits > 32)
46+
long_in <= 1;
47+
end
48+
49+
always @(posedge clk)
50+
if (~(in32_hold & in32_valid))
51+
if (long_in) begin
52+
in32_nbits <= in_nbits - 32;
53+
in32_data <= in_data;
54+
in32_tlast <= in_tlast;
55+
end
56+
else if (in_valid)
57+
if (in_nbits > 32) begin
58+
in32_nbits <= 32;
59+
in32_data <= in_data >> 32;
60+
in32_tlast <= 0;
61+
end
62+
else begin
63+
in32_nbits <= in_nbits;
64+
in32_data <= in_data >> 32;
65+
in32_tlast <= in_tlast;
66+
end
67+
68+
// Stall to split 32+ into 32 + remainder
69+
always_comb in_hold = (in32_hold & in32_valid) | (~long_in & in_nbits > 32); // goes out
70+
71+
72+
// 2.) incoming: 32 bits max = 4 bytes
73+
// send data when more than 31 bits in storage
74+
logic [5:0] bit_count, next_bit_count, next_bit_count_incr, next_bit_count_decr;
75+
logic [63:0] bit_packer, next_bit_packer, next_bit_packer_load;
76+
logic [5:0] next_bit_packer_shift;
77+
logic tlast_cycle, next_tlast_cycle;
78+
logic next_out_tlast;
79+
80+
always_comb out_data = (bit_packer >> 32) | (out_tlast ? (32'hffffffff >> bit_count) : 0);
81+
always_comb next_bit_count = bit_count + next_bit_count_incr - next_bit_count_decr;
82+
always_comb next_bit_packer = (bit_packer << next_bit_packer_shift) | (next_bit_packer_load << (32 + next_bit_count_decr - bit_count));
83+
84+
always_comb begin
85+
if (out_tlast) begin
86+
next_bit_count_decr = bit_count;
87+
next_bit_packer_shift = 32;
88+
end
89+
else if (bit_count >= 32) begin
90+
next_bit_count_decr = 32;
91+
next_bit_packer_shift = 32;
92+
end
93+
else begin
94+
next_bit_count_decr = 0;
95+
next_bit_packer_shift = 0;
96+
end
97+
98+
if (in32_valid & ~in32_hold) begin
99+
next_bit_count_incr = in32_nbits;
100+
next_bit_packer_load = in32_data;
101+
end
102+
else begin
103+
next_bit_count_incr = 0;
104+
next_bit_packer_load = 0;
105+
end
106+
107+
if (tlast_cycle)
108+
next_tlast_cycle = ~out_tlast;
109+
else if (in32_valid)
110+
next_tlast_cycle = in32_tlast;
111+
else
112+
next_tlast_cycle = tlast_cycle;
113+
end
114+
115+
always @(posedge clk)
116+
if (!resetn) begin
117+
bit_count <= 0;
118+
tlast_cycle <= 0;
119+
out_tlast <= 0;
120+
out_valid <= 0;
121+
bit_packer <= 0;
122+
end
123+
else if (~(out_hold & out_valid)) begin
124+
bit_count <= next_bit_count;
125+
tlast_cycle <= next_tlast_cycle;
126+
127+
out_tlast <= next_tlast_cycle & next_bit_count <= 32;
128+
out_valid <= (next_tlast_cycle & next_bit_count <= 32) | next_bit_count >= 32; //always_comb out_valid = out_tlast | bit_count >= 32;
129+
130+
bit_packer <= next_bit_packer;
131+
end
132+
133+
always @(posedge clk)
134+
if (~(out_hold & out_valid))
135+
out_nbytes <= (next_tlast_cycle & next_bit_count <= 32) ? (next_bit_count + 7) >> 3 : 4; // always_comb out_nbytes = out_tlast ? (bit_count + 7) >> 3 : 4;
136+
137+
always_comb in32_hold = (out_hold & out_valid) | (tlast_cycle & ~out_tlast);
138+
139+
endmodule

source/fpga/modules/camera/jpeg_encoder/jenc/bitpacker.sv

-80
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Authored by: Robert Metchev / Chips & Scripts (rmetchev@ieee.org)
3+
*
4+
* CERN Open Hardware Licence Version 2 - Permissive
5+
*
6+
* Copyright (C) 2024 Robert Metchev
7+
*/
8+
module byte_pack (
9+
//packed code+coeff
10+
input logic [5:0] codecoeff_length,
11+
input logic [51:0] codecoeff,
12+
input logic codecoeff_tlast,
13+
input logic codecoeff_valid,
14+
output logic codecoeff_hold,
15+
16+
output logic [31:0] out_data,
17+
output logic out_tlast,
18+
output logic out_valid,
19+
input logic out_hold,
20+
21+
input logic clk,
22+
input logic resetn
23+
);
24+
25+
// Pack up to 52 bits into 4 byte words
26+
logic [31:0] data_0;
27+
logic [2:0] nbytes_0;
28+
logic tlast_0;
29+
logic valid_0;
30+
logic hold_0;
31+
32+
bit_pack bit_pack_0 (
33+
.in_data ({codecoeff, 12'h0}),
34+
.in_nbits ({1'b0, codecoeff_length}),
35+
.in_tlast (codecoeff_tlast),
36+
.in_valid (codecoeff_valid),
37+
.in_hold (codecoeff_hold),
38+
39+
.out_data (data_0),
40+
.out_nbytes (nbytes_0),
41+
.out_tlast (tlast_0),
42+
.out_valid (valid_0),
43+
.out_hold (hold_0 & valid_0),
44+
45+
.*
46+
);
47+
48+
// pad 0xFF with 0x00
49+
logic [63:0] data_1;
50+
logic [3:0] nbytes_1;
51+
logic tlast_1;
52+
logic valid_1;
53+
logic hold_1;
54+
55+
ff00 ff00 (
56+
.in_data (data_0),
57+
.in_nbytes (nbytes_0),
58+
.in_tlast (tlast_0),
59+
.in_valid (valid_0),
60+
.in_hold (hold_0),
61+
62+
.out_data (data_1),
63+
.out_nbytes (nbytes_1),
64+
.out_tlast (tlast_1),
65+
.out_valid (valid_1),
66+
.out_hold (hold_1 & valid_1),
67+
68+
.*
69+
);
70+
71+
// Pack up to 8 bytes into 4 byte words
72+
bit_pack bit_pack_1 (
73+
.in_data (data_1),
74+
.in_nbits ({nbytes_1, 3'h0}), // bytes -> bits
75+
.in_tlast (tlast_1),
76+
.in_valid (valid_1),
77+
.in_hold (hold_1),
78+
79+
.out_nbytes ( ), // always full 32 bits/4 bytes
80+
.out_hold (out_hold & out_valid),
81+
82+
.*
83+
);
84+
85+
endmodule

0 commit comments

Comments
 (0)