1 |
25 |
mikel262 |
-------------------------------------------------------------------------------
|
2 |
|
|
-- File Name : JFIFGen.vhd
|
3 |
|
|
--
|
4 |
|
|
-- Project : JPEG_ENC
|
5 |
|
|
--
|
6 |
|
|
-- Module : JFIFGen
|
7 |
|
|
--
|
8 |
|
|
-- Content : JFIF Header Generator
|
9 |
|
|
--
|
10 |
|
|
-- Description :
|
11 |
|
|
--
|
12 |
|
|
-- Spec. :
|
13 |
|
|
--
|
14 |
|
|
-- Author : Michal Krepa
|
15 |
|
|
--
|
16 |
|
|
-------------------------------------------------------------------------------
|
17 |
|
|
-- History :
|
18 |
|
|
-- 20090309: (MK): Initial Creation.
|
19 |
|
|
-------------------------------------------------------------------------------
|
20 |
|
|
|
21 |
|
|
-------------------------------------------------------------------------------
|
22 |
|
|
-------------------------------------------------------------------------------
|
23 |
|
|
----------------------------------- LIBRARY/PACKAGE ---------------------------
|
24 |
|
|
-------------------------------------------------------------------------------
|
25 |
|
|
-------------------------------------------------------------------------------
|
26 |
|
|
|
27 |
|
|
-------------------------------------------------------------------------------
|
28 |
|
|
-- generic packages/libraries:
|
29 |
|
|
-------------------------------------------------------------------------------
|
30 |
|
|
library ieee;
|
31 |
|
|
use ieee.std_logic_1164.all;
|
32 |
|
|
use ieee.numeric_std.all;
|
33 |
|
|
|
34 |
|
|
library work;
|
35 |
|
|
use work.JPEG_PKG.all;
|
36 |
|
|
|
37 |
|
|
-------------------------------------------------------------------------------
|
38 |
|
|
-- user packages/libraries:
|
39 |
|
|
-------------------------------------------------------------------------------
|
40 |
|
|
|
41 |
|
|
-------------------------------------------------------------------------------
|
42 |
|
|
-------------------------------------------------------------------------------
|
43 |
|
|
----------------------------------- ENTITY ------------------------------------
|
44 |
|
|
-------------------------------------------------------------------------------
|
45 |
|
|
-------------------------------------------------------------------------------
|
46 |
|
|
entity JFIFGen is
|
47 |
|
|
port
|
48 |
|
|
(
|
49 |
|
|
CLK : in std_logic;
|
50 |
|
|
RST : in std_logic;
|
51 |
|
|
-- CTRL
|
52 |
|
|
start : in std_logic;
|
53 |
|
|
ready : out std_logic;
|
54 |
|
|
eoi : in std_logic;
|
55 |
|
|
|
56 |
|
|
-- ByteStuffer
|
57 |
|
|
num_enc_bytes : in std_logic_vector(23 downto 0);
|
58 |
|
|
|
59 |
|
|
-- HOST IF
|
60 |
|
|
qwren : in std_logic;
|
61 |
32 |
mikel262 |
qwaddr : in std_logic_vector(6 downto 0);
|
62 |
25 |
mikel262 |
qwdata : in std_logic_vector(7 downto 0);
|
63 |
|
|
image_size_reg : in std_logic_vector(31 downto 0);
|
64 |
|
|
image_size_reg_wr : in std_logic;
|
65 |
|
|
|
66 |
|
|
-- OUT RAM
|
67 |
|
|
ram_byte : out std_logic_vector(7 downto 0);
|
68 |
|
|
ram_wren : out std_logic;
|
69 |
|
|
ram_wraddr : out std_logic_vector(23 downto 0)
|
70 |
|
|
);
|
71 |
|
|
end entity JFIFGen;
|
72 |
|
|
|
73 |
|
|
-------------------------------------------------------------------------------
|
74 |
|
|
-------------------------------------------------------------------------------
|
75 |
|
|
----------------------------------- ARCHITECTURE ------------------------------
|
76 |
|
|
-------------------------------------------------------------------------------
|
77 |
|
|
-------------------------------------------------------------------------------
|
78 |
|
|
architecture RTL of JFIFGen is
|
79 |
|
|
|
80 |
|
|
constant C_SIZE_Y_H : integer := 25;
|
81 |
|
|
constant C_SIZE_Y_L : integer := 26;
|
82 |
|
|
constant C_SIZE_X_H : integer := 27;
|
83 |
|
|
constant C_SIZE_X_L : integer := 28;
|
84 |
|
|
|
85 |
|
|
constant C_EOI : std_logic_vector(15 downto 0) := X"FFD9";
|
86 |
32 |
mikel262 |
constant C_QLUM_BASE : integer := 44;
|
87 |
|
|
constant C_QCHR_BASE : integer := 44+69;
|
88 |
25 |
mikel262 |
|
89 |
|
|
|
90 |
|
|
signal hr_data : std_logic_vector(7 downto 0);
|
91 |
36 |
mikel262 |
signal hr_waddr : std_logic_vector(9 downto 0);
|
92 |
|
|
signal hr_raddr : std_logic_vector(9 downto 0);
|
93 |
25 |
mikel262 |
signal hr_we : std_logic;
|
94 |
|
|
signal hr_q : std_logic_vector(7 downto 0);
|
95 |
|
|
signal size_wr_cnt : unsigned(2 downto 0);
|
96 |
|
|
signal size_wr : std_logic;
|
97 |
36 |
mikel262 |
signal rd_cnt : unsigned(9 downto 0);
|
98 |
25 |
mikel262 |
signal rd_en : std_logic;
|
99 |
|
|
signal rd_en_d1 : std_logic;
|
100 |
36 |
mikel262 |
signal rd_cnt_d1 : unsigned(rd_cnt'range);
|
101 |
|
|
signal rd_cnt_d2 : unsigned(rd_cnt'range);
|
102 |
25 |
mikel262 |
signal eoi_cnt : unsigned(1 downto 0);
|
103 |
|
|
signal eoi_wr : std_logic;
|
104 |
|
|
signal eoi_wr_d1 : std_logic;
|
105 |
|
|
|
106 |
37 |
mikel262 |
component HeaderRam is
|
107 |
|
|
port
|
108 |
|
|
(
|
109 |
|
|
d : in STD_LOGIC_VECTOR(7 downto 0);
|
110 |
|
|
waddr : in STD_LOGIC_VECTOR(9 downto 0);
|
111 |
|
|
raddr : in STD_LOGIC_VECTOR(9 downto 0);
|
112 |
|
|
we : in STD_LOGIC;
|
113 |
|
|
clk : in STD_LOGIC;
|
114 |
|
|
|
115 |
|
|
q : out STD_LOGIC_VECTOR(7 downto 0)
|
116 |
|
|
);
|
117 |
|
|
end component;
|
118 |
|
|
|
119 |
25 |
mikel262 |
-------------------------------------------------------------------------------
|
120 |
|
|
-- Architecture: begin
|
121 |
|
|
-------------------------------------------------------------------------------
|
122 |
|
|
begin
|
123 |
|
|
|
124 |
|
|
-------------------------------------------------------------------
|
125 |
|
|
-- Header RAM
|
126 |
|
|
-------------------------------------------------------------------
|
127 |
38 |
mikel262 |
U_Header_RAM : HeaderRam
|
128 |
25 |
mikel262 |
port map
|
129 |
|
|
(
|
130 |
|
|
d => hr_data,
|
131 |
|
|
waddr => hr_waddr,
|
132 |
|
|
raddr => hr_raddr,
|
133 |
|
|
we => hr_we,
|
134 |
|
|
clk => CLK,
|
135 |
|
|
|
136 |
|
|
q => hr_q
|
137 |
|
|
);
|
138 |
|
|
|
139 |
|
|
hr_raddr <= std_logic_vector(rd_cnt);
|
140 |
|
|
|
141 |
|
|
-------------------------------------------------------------------
|
142 |
|
|
-- Host programming
|
143 |
|
|
-------------------------------------------------------------------
|
144 |
|
|
p_host_wr : process(CLK, RST)
|
145 |
|
|
begin
|
146 |
|
|
if RST = '1' then
|
147 |
|
|
size_wr_cnt <= (others => '0');
|
148 |
|
|
size_wr <= '0';
|
149 |
|
|
hr_we <= '0';
|
150 |
|
|
hr_data <= (others => '0');
|
151 |
|
|
hr_waddr <= (others => '0');
|
152 |
|
|
elsif CLK'event and CLK = '1' then
|
153 |
|
|
hr_we <= '0';
|
154 |
|
|
|
155 |
|
|
if image_size_reg_wr = '1' then
|
156 |
|
|
size_wr_cnt <= (others => '0');
|
157 |
|
|
size_wr <= '1';
|
158 |
|
|
end if;
|
159 |
|
|
|
160 |
|
|
-- write image size
|
161 |
|
|
if size_wr = '1' then
|
162 |
|
|
if size_wr_cnt = 4 then
|
163 |
|
|
size_wr_cnt <= (others => '0');
|
164 |
|
|
size_wr <= '0';
|
165 |
|
|
else
|
166 |
|
|
size_wr_cnt <= size_wr_cnt + 1;
|
167 |
|
|
hr_we <= '1';
|
168 |
|
|
case size_wr_cnt is
|
169 |
|
|
-- height H byte
|
170 |
|
|
when "000" =>
|
171 |
|
|
hr_data <= image_size_reg(15 downto 8);
|
172 |
|
|
hr_waddr <= std_logic_vector(to_unsigned(C_SIZE_Y_H,hr_waddr'length));
|
173 |
|
|
-- height L byte
|
174 |
|
|
when "001" =>
|
175 |
|
|
hr_data <= image_size_reg(7 downto 0);
|
176 |
|
|
hr_waddr <= std_logic_vector(to_unsigned(C_SIZE_Y_L,hr_waddr'length));
|
177 |
|
|
-- width H byte
|
178 |
|
|
when "010" =>
|
179 |
|
|
hr_data <= image_size_reg(31 downto 24);
|
180 |
|
|
hr_waddr <= std_logic_vector(to_unsigned(C_SIZE_X_H,hr_waddr'length));
|
181 |
|
|
-- width L byte
|
182 |
|
|
when "011" =>
|
183 |
|
|
hr_data <= image_size_reg(23 downto 16);
|
184 |
|
|
hr_waddr <= std_logic_vector(to_unsigned(C_SIZE_X_L,hr_waddr'length));
|
185 |
|
|
when others =>
|
186 |
|
|
null;
|
187 |
|
|
end case;
|
188 |
|
|
end if;
|
189 |
|
|
-- write Quantization table
|
190 |
|
|
elsif qwren = '1' then
|
191 |
32 |
mikel262 |
-- luminance table select
|
192 |
|
|
if qwaddr(6) = '0' then
|
193 |
|
|
hr_waddr <= std_logic_vector
|
194 |
|
|
( resize(unsigned(qwaddr(5 downto 0)),hr_waddr'length) +
|
195 |
|
|
to_unsigned(C_QLUM_BASE,hr_waddr'length));
|
196 |
|
|
else
|
197 |
|
|
-- chrominance table select
|
198 |
|
|
hr_waddr <= std_logic_vector
|
199 |
|
|
( resize(unsigned(qwaddr(5 downto 0)),hr_waddr'length) +
|
200 |
|
|
to_unsigned(C_QCHR_BASE,hr_waddr'length));
|
201 |
|
|
end if;
|
202 |
25 |
mikel262 |
hr_we <= '1';
|
203 |
|
|
hr_data <= qwdata;
|
204 |
|
|
end if;
|
205 |
|
|
|
206 |
|
|
end if;
|
207 |
|
|
end process;
|
208 |
|
|
|
209 |
|
|
-------------------------------------------------------------------
|
210 |
|
|
-- CTRL
|
211 |
|
|
-------------------------------------------------------------------
|
212 |
|
|
p_ctrl : process(CLK, RST)
|
213 |
|
|
begin
|
214 |
|
|
if RST = '1' then
|
215 |
|
|
ready <= '0';
|
216 |
|
|
rd_en <= '0';
|
217 |
|
|
rd_cnt <= (others => '0');
|
218 |
|
|
rd_cnt_d1 <= (others => '0');
|
219 |
|
|
rd_cnt_d2 <= (others => '0');
|
220 |
|
|
rd_cnt_d1 <= (others => '0');
|
221 |
|
|
rd_en_d1 <= '0';
|
222 |
|
|
eoi_wr_d1 <= '0';
|
223 |
|
|
eoi_wr <= '0';
|
224 |
|
|
eoi_cnt <= (others => '0');
|
225 |
|
|
ram_wren <= '0';
|
226 |
|
|
ram_byte <= (others => '0');
|
227 |
|
|
ram_wraddr <= (others => '0');
|
228 |
|
|
elsif CLK'event and CLK = '1' then
|
229 |
|
|
ready <= '0';
|
230 |
|
|
rd_cnt_d1 <= rd_cnt;
|
231 |
|
|
rd_cnt_d2 <= rd_cnt_d1;
|
232 |
|
|
rd_en_d1 <= rd_en;
|
233 |
|
|
eoi_wr_d1 <= eoi_wr;
|
234 |
|
|
|
235 |
|
|
-- defaults: encoded data write
|
236 |
|
|
ram_wren <= rd_en_d1;
|
237 |
|
|
ram_wraddr <= std_logic_vector(resize(rd_cnt_d1,ram_wraddr'length));
|
238 |
|
|
ram_byte <= hr_q;
|
239 |
|
|
|
240 |
|
|
-- start JFIF
|
241 |
|
|
if start = '1' and eoi = '0' then
|
242 |
|
|
rd_cnt <= (others => '0');
|
243 |
|
|
rd_en <= '1';
|
244 |
|
|
elsif start = '1' and eoi = '1' then
|
245 |
|
|
eoi_wr <= '1';
|
246 |
|
|
eoi_cnt <= (others => '0');
|
247 |
|
|
end if;
|
248 |
|
|
|
249 |
|
|
-- read JFIF Header
|
250 |
|
|
if rd_en = '1' then
|
251 |
|
|
if rd_cnt = C_HDR_SIZE-1 then
|
252 |
|
|
rd_en <= '0';
|
253 |
|
|
ready <= '1';
|
254 |
|
|
else
|
255 |
|
|
rd_cnt <= rd_cnt + 1;
|
256 |
|
|
end if;
|
257 |
|
|
end if;
|
258 |
|
|
|
259 |
|
|
-- EOI MARKER write
|
260 |
|
|
if eoi_wr = '1' then
|
261 |
|
|
if eoi_cnt = 2 then
|
262 |
|
|
eoi_cnt <= (others => '0');
|
263 |
|
|
eoi_wr <= '0';
|
264 |
|
|
ready <= '1';
|
265 |
|
|
else
|
266 |
|
|
eoi_cnt <= eoi_cnt + 1;
|
267 |
|
|
ram_wren <= '1';
|
268 |
|
|
if eoi_cnt = 0 then
|
269 |
|
|
ram_byte <= C_EOI(15 downto 8);
|
270 |
|
|
ram_wraddr <= num_enc_bytes;
|
271 |
|
|
elsif eoi_cnt = 1 then
|
272 |
|
|
ram_byte <= C_EOI(7 downto 0);
|
273 |
|
|
ram_wraddr <= std_logic_vector(unsigned(num_enc_bytes) +
|
274 |
|
|
to_unsigned(1,ram_wraddr'length));
|
275 |
|
|
end if;
|
276 |
|
|
end if;
|
277 |
|
|
end if;
|
278 |
|
|
end if;
|
279 |
|
|
end process;
|
280 |
|
|
|
281 |
|
|
end architecture RTL;
|
282 |
|
|
-------------------------------------------------------------------------------
|
283 |
|
|
-- Architecture: end
|
284 |
|
|
-------------------------------------------------------------------------------
|