-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathencoder.vhd
294 lines (234 loc) · 9.75 KB
/
encoder.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
library ieee_proposed;
use ieee_proposed.fixed_pkg.all;
use work.jpeg_pkg.all;
-- TODO: potential ZRL bug, ZRL may mean 16 zeros not 15 because its (F, 0), should be easy fix
entity encoder is
port (
clock : in std_logic;
clr : in std_logic;
increment_block_count : in std_logic;
channel : in integer range 0 to 3;
dct_coeff_zz : in dct_coeff_zz_t;
encoding_done : out std_logic;
length_o : out integer range 0 to 512;
encoded_block : out std_logic_vector(511 downto 0)
) ;
end encoder;
architecture arch of encoder is
signal y_dc_code : y_dc_code_t ;
signal c_dc_code : c_dc_code_t ;
signal y_ac_code : ac_code_t ;
signal dc_huff_value,ac_huff_value : huff_value_t;
signal huff_code, dc_huff_code, dc_huff_code_y ,dc_huff_code_c, eob : huff_code_t;
signal dc_coeff_diff : sfixed(11 downto 0);
signal code_ready,encoding_done_s,delay, table_load, manual,concat, concat_done, length_add, length_add_reset : std_logic;
signal zrl_flag : std_logic_vector(2 downto 0) := "000";
signal ac_huff_code,ac_huff_code_2, temp_reg : huff_code_t;
signal run_length : integer range 0 to 63 := 0;
signal huff_code_index : integer range 0 to 63 := 0;
signal encoded_block_s : std_logic_vector(511 downto 0);
signal length : integer range 0 to 512;
signal prev_dc_y, prev_dc_cb, prev_dc_cr : sfixed(10 downto 0) := "00000000000";
signal huff_value_zz : huff_value_zz_t;
signal temp : std_logic_vector(511 downto 0);
shared variable temp_y, temp_y2, temp_c, temp_c2 : std_logic_vector(511 downto 0);
begin
length_o <= length;
encoding_done <= encoding_done_s;
encoded_block <= encoded_block_s;
old_dc_reg_pr : process(clock )
begin
if rising_edge(clock) and encoding_done_s = '1' then
if channel = 0 then
prev_dc_y <= dct_coeff_zz(0);
elsif channel = 1 then
prev_dc_cb <= dct_coeff_zz(0);
elsif channel = 2 then
prev_dc_cr <= dct_coeff_zz(0);
end if;
end if;
end process ; -- old_dc_reg_pr
mini_length_comp : mini_length_block port map(clock,increment_block_count ,channel , prev_dc_y, prev_dc_cb, prev_dc_cr, dct_coeff_zz, huff_value_zz);
eob <= y_eob when channel = 0 else c_eob;
y_dc_code <= y_dc_codes(huff_value_zz(0).code_length);
c_dc_code <= c_dc_codes(huff_value_zz(0).code_length);
dc_huff_value <= huff_value_zz(0);
dc_huff_code_y <= y_dc_code + dc_huff_value;
dc_huff_code_c <= c_dc_code + dc_huff_value;
dc_huff_code <= dc_huff_code_y when channel = 0 else dc_huff_code_c;
ac_huff_value <= huff_value_zz(huff_code_index);
ac_table_comp : ac_huff_table port map(clock, clr, channel, run_length, ac_huff_value, table_load, ac_huff_code, code_ready);
concatination_on_going : process( clock )
begin
if clr = '0' or encoding_done_s = '1' or concat_done = '1' then
concat <= '0';
elsif falling_edge(table_load) then
concat <= '1';
end if;
end process ; -- shifting_on_going
huff_code_index_pr : process(clock)
begin
if clr = '0' then
huff_code_index <= 0;
encoding_done_s <= '0';
elsif falling_edge(clock) and concat = '0' and table_load = '1' and code_ready = '0' then
if huff_code_index = 63 then
encoding_done_s <= '1';
else
huff_code_index <= huff_code_index + 1;
encoding_done_s <= '0';
end if;
end if;
end process ;
ac_encoding : process(clock,encoding_done_s)
begin
if clr = '0' or encoding_done_s = '1' then
run_length <= 0;
zrl_flag <= "000";
table_load <= '1';
elsif rising_edge(clock) and table_load = '0' and code_ready = '1' then
table_load <= '1';
run_length <= 0;
elsif rising_edge(clock) and concat = '0' then
if huff_code_index = 0 then
table_load <= '0';
zrl_flag <= "000";
elsif ac_huff_value.code_length = 0 and huff_code_index = 63 then
table_load <= '0';
zrl_flag <= "000";
elsif ac_huff_value.code_length = 0 then
run_length <= run_length + 1;
table_load <= '1';
zrl_flag <= "000";
-- elsif run_length > 63 then
-- zrl_flag <= "100";
-- run_length <= run_length - 64';
-- table_load <= '0';
elsif run_length > 47 then
zrl_flag <= "011";
run_length <= run_length - 46;
table_load <= '0';
elsif run_length > 31 then
zrl_flag <= "010";
run_length <= run_length - 32;
table_load <= '0';
elsif run_length > 15 then
zrl_flag <= "001";
run_length <= run_length - 16;
table_load <= '0';
else
zrl_flag <= "000";
run_length <= run_length;
table_load <= '0';
end if;
end if;
end process ; -- ac_encoding
huff_code_pro : process( clock )
begin
if rising_edge(clock) then
if huff_code_index = 0 then
huff_code <= dc_huff_code; -- dc code
elsif ac_huff_value.code_length = 0 and huff_code_index = 63 then
huff_code <= eob;
else
huff_code <= ac_huff_code;
end if;
end if;
end process ; -- huff_code_pro
writing_pr_y : process(clock)
begin
if clr = '0' then
temp_y := (others => '0');
temp_y2 := (others => '0');
else
if zrl_flag = "000" then
temp_y(511 downto 485) := huff_code.code;
temp_y(484 downto 0) := (others => '0');
-- length <= length + ac_huff_code.code_length;
elsif zrl_flag = "001" then
temp_y(511 downto 501) := y_zrl;
temp_y(500 downto 474) := huff_code.code;
temp_y(473 downto 0) := (others => '0');
-- length <= length + ac_huff_code.code_length + 11;
elsif zrl_flag = "010" then
temp_y(511 downto 501) := y_zrl;
temp_y(500 downto 490) := y_zrl;
temp_y(489 downto 463) := huff_code.code;
temp_y(462 downto 0) := (others => '0');
-- length <= length + ac_huff_code.code_length + 22;
else
temp_y(511 downto 501) := y_zrl;
temp_y(500 downto 490) := y_zrl;
temp_y(489 downto 479) := y_zrl;
temp_y(478 downto 452) := huff_code.code;
temp_y(451 downto 0) := (others => '0');
end if;
temp_y2 := shiftr(temp_y, length);
end if;
end process ; -- identifier
writing_pr_c : process(clock)
begin
if clr = '0' then
temp_c := (others => '0');
temp_c2 := (others => '0');
else
if zrl_flag = "000" then
temp_c(511 downto 485) := huff_code.code;
temp_c(484 downto 0) := (others => '0');
-- length <= length + ac_huff_code.code_length;
elsif zrl_flag = "001" then
temp_c(511 downto 502) := c_zrl;
temp_c(501 downto 475) := huff_code.code;
temp_c(474 downto 0) := (others => '0');
-- length <= length + ac_huff_code.code_length + 11;
elsif zrl_flag = "010" then
temp_c(511 downto 502) := c_zrl;
temp_c(501 downto 492) := c_zrl;
temp_c(491 downto 465) := huff_code.code;
temp_c(464 downto 0) := (others => '0');
-- length <= length + ac_huff_code.code_length + 22;
else
temp_c(511 downto 502) := c_zrl;
temp_c(501 downto 492) := c_zrl;
temp_c(491 downto 482) := c_zrl;
temp_c(481 downto 455) := huff_code.code;
temp_c(454 downto 0) := (others => '0');
end if;
temp_c2 := shiftr(temp_c, length);
end if;
end process ; -- identifier
temp <= temp_y2 when channel = 0 else temp_c2;
falling_edge_encoded_block_output : process(clock )
variable delay_counter : integer range 0 to 3;
begin
if clr = '0' then
encoded_block_s <= (others => '0');
length <= 0;
delay_counter := 0;
concat_done <= '0';
elsif rising_edge(clock) and concat = '1' then
if code_ready = '1' then
delay_counter := 1;
concat_done <= '0';
elsif delay_counter = 1 then
encoded_block_s <= encoded_block_s or temp;
length <= length + huff_code.code_length + to_integer(unsigned(zrl_flag)) * 11 ;
concat_done <= '0';
delay_counter := 2;
elsif delay_counter = 2 then
delay_counter := 3;
concat_done <= '0';
elsif delay_counter = 3 then
delay_counter := 0;
concat_done <= '1';
end if;
elsif rising_edge(clock) then
concat_done <= '0';
delay_counter := 0;
end if;
end process ; -- falling_edge_encoded_block_output
end arch ; -- arch