1 -------------------------------------------------------------------------------
3 -- File : rgb3sx8_to_ycbcr_3DSP.vhd
6 -- Author(s) : stephane Domas (sdomas@univ-fcomte.fr)
8 -- Creation Date : 2017/10/16
10 -- Description : This IP does a conversion from rgb24 (8 bits/serial) to YCrCb
12 -- Note : rgb24 (8 bits/serial) pixels are composed of three 8 bits
13 -- values that are consumed on port rgb_in, in the following
14 -- order : blue, green, red.
15 -- output values on ycrcb_out are produced in the following
17 -- They are computed using ITU-R BT.601 conversion principles,
18 -- assuming that RGB component are digital and thus rangin
19 -- from 0 to 255. Formulas are:
20 -- Y = 16 + 65.738R/256 + 129.057G/256 + 25.064B/256
21 -- Cb = 128 - 37.945R/256 - 74.494G/256 + 112.439B/256
22 -- Cr = 128 + 112.439R/256 - 94.154G/256 - 18.285B/256
24 -------------------------------------------------------------------------------
27 use IEEE.std_logic_1164.all;
28 use IEEE.numeric_std.all;
30 entity rgb3sx8_to_ycbcr_3DSP is
34 rgb_in : in std_logic_vector(7 downto 0);
35 rgb_in_enb : in std_logic;
36 ycbcr_out : out std_logic_vector(7 downto 0);
37 ycbcr_out_enb : out std_logic
40 end rgb3sx8_to_ycbcr_3DSP;
43 architecture rtl of rgb3sx8_to_ycbcr_3DSP is
50 bypass : in std_logic;
51 a : in std_logic_vector(17 downto 0);
52 b : in std_logic_vector(17 downto 0);
53 s : out std_logic_vector(47 downto 0)
58 signal do_sum_y : std_logic;
59 signal do_sum_y_dly : std_logic;
60 signal do_sum_cr : std_logic;
61 signal do_sum_cr_dly : std_logic;
62 signal do_sum_cb : std_logic;
63 signal do_sum_cb_dly : std_logic;
64 signal do_out : std_logic;
65 signal do_out_cr : std_logic;
66 signal do_out_cb : std_logic;
67 signal do_out_y : std_logic;
68 signal count_y : unsigned (2 downto 0);
69 signal count_cr : unsigned (2 downto 0);
70 signal count_cb : unsigned (2 downto 0);
71 signal y : signed(8 downto 0);
72 signal y_dly1 : signed(8 downto 0);
73 signal y_dly2 : signed(8 downto 0);
74 signal cb : signed(8 downto 0);
75 signal cb_dly1 : signed(8 downto 0);
76 signal cr : signed(8 downto 0);
77 signal cst_y_r : signed(17 downto 0);
78 signal cst_y_g : signed(17 downto 0);
79 signal cst_y_b : signed(17 downto 0);
80 signal cst_cb_r : signed(17 downto 0);
81 signal cst_cb_g : signed(17 downto 0);
82 signal cst_cb_b : signed(17 downto 0);
83 signal cst_cr_r : signed(17 downto 0);
84 signal cst_cr_g : signed(17 downto 0);
85 signal cst_cr_b : signed(17 downto 0);
87 signal bypass_y : std_logic;
88 signal a_y : std_logic_vector(17 downto 0);
89 signal b_y : std_logic_vector(17 downto 0);
90 signal s_y : std_logic_vector(47 downto 0);
91 signal bypass_cr : std_logic;
92 signal a_cr : std_logic_vector(17 downto 0);
93 signal b_cr : std_logic_vector(17 downto 0);
94 signal s_cr : std_logic_vector(47 downto 0);
95 signal bypass_cb : std_logic;
96 signal a_cb : std_logic_vector(17 downto 0);
97 signal b_cb : std_logic_vector(17 downto 0);
98 signal s_cb : std_logic_vector(47 downto 0);
100 signal compo_out : std_logic_vector(7 downto 0);
104 y_multiplier : mult_accum
114 cr_multiplier : mult_accum
124 cb_multiplier : mult_accum
136 cst_y_r <= to_signed(33658, 18);
137 cst_y_g <= to_signed(66077, 18);
138 cst_y_b <= to_signed(12833, 18);
139 cst_cb_r <= to_signed(-19428, 18);
140 cst_cb_g <= to_signed(-38141, 18);
141 cst_cb_b <= to_signed(57569, 18);
142 cst_cr_r <= to_signed(57569, 18);
143 cst_cr_g <= to_signed(-48207, 18);
144 cst_cr_b <= to_signed(-9362, 18);
146 multy_process : process (clk, reset)
149 a_y <= (others => '0');
150 b_y <= (others => '0');
152 count_y <= to_unsigned(0, 3);
155 elsif rising_edge(clk) then
159 a_y <= (others => '0');
160 b_y <= (others => '0');
162 if rgb_in_enb = '1' then
164 a_y <= "0000000000" & rgb_in;
167 b_y <= std_logic_vector(cst_y_b);
169 count_y <= to_unsigned(1, 3);
171 elsif count_y = 1 then
172 b_y <= std_logic_vector(cst_y_g);
173 count_y <= to_unsigned(2, 3);
175 elsif count_y = 2 then
176 b_y <= std_logic_vector(cst_y_r);
177 count_y <= to_unsigned(0, 3);
182 end process multy_process;
184 sumy_process : process (clk, reset)
188 y <= to_signed(0, 9);
189 y_dly1 <= to_signed(0, 9);
190 y_dly2 <= to_signed(0, 9);
192 elsif rising_edge(clk) then
193 bypass_y <= do_sum_y;
194 do_sum_y_dly <= do_sum_y;
198 if do_sum_y_dly = '1' then
199 y <= to_signed(16, 9) + signed(s_y(25 downto 17));
203 end process sumy_process;
205 multcb_process : process (clk, reset)
208 a_cb <= (others => '0');
209 b_cb <= (others => '0');
211 count_cb <= to_unsigned(0, 3);
214 elsif rising_edge(clk) then
218 a_cb <= (others => '0');
219 b_cb <= (others => '0');
221 if rgb_in_enb = '1' then
223 a_cb <= "0000000000" & rgb_in;
226 b_cb <= std_logic_vector(cst_cb_b);
228 count_cb <= to_unsigned(1, 3);
230 elsif count_cb = 1 then
231 b_cb <= std_logic_vector(cst_cb_g);
232 count_cb <= to_unsigned(2, 3);
234 elsif count_cb = 2 then
235 b_cb <= std_logic_vector(cst_cb_r);
236 count_cb <= to_unsigned(0, 3);
241 end process multcb_process;
243 sumcb_process : process (clk, reset)
247 cb <= to_signed(0, 9);
248 cb_dly1 <= to_signed(0, 9);
249 elsif rising_edge(clk) then
250 bypass_cb <= do_sum_cb;
251 do_sum_cb_dly <= do_sum_cb;
254 if do_sum_cb_dly = '1' then
255 cb <= to_signed(128, 9) + signed(s_cb(25 downto 17));
259 end process sumcb_process;
261 multcr_process : process (clk, reset)
264 a_cr <= (others => '0');
265 b_cr <= (others => '0');
267 count_cr <= to_unsigned(0, 3);
270 elsif rising_edge(clk) then
274 a_cr <= (others => '0');
275 b_cr <= (others => '0');
277 if rgb_in_enb = '1' then
279 a_cr <= "0000000000" & rgb_in;
282 b_cr <= std_logic_vector(cst_cr_b);
284 count_cr <= to_unsigned(1, 3);
286 elsif count_cr = 1 then
287 b_cr <= std_logic_vector(cst_cr_g);
288 count_cr <= to_unsigned(2, 3);
290 elsif count_cr = 2 then
291 b_cr <= std_logic_vector(cst_cr_r);
292 count_cr <= to_unsigned(0, 3);
297 end process multcr_process;
299 sumcr_process : process (clk, reset)
303 cr <= to_signed(0, 9);
306 elsif rising_edge(clk) then
307 bypass_cr <= do_sum_cr;
308 do_sum_cr_dly <= do_sum_cr;
311 if do_sum_cr_dly = '1' then
313 cr <= to_signed(128, 9) + signed(s_cr(25 downto 17));
316 end process sumcr_process;
318 out_process : process (clk, reset)
323 elsif rising_edge(clk) then
324 do_out_cb <= do_out_cr;
325 do_out_y <= do_out_cb;
327 end process out_process;
330 ycbcr_out <= std_logic_vector(y_dly2(7 downto 0)) when do_out_y = '1' else
331 std_logic_vector(cb_dly1(7 downto 0)) when do_out_cb = '1' else
332 std_logic_vector(cr(7 downto 0)) when do_out_cr = '1' else
334 ycbcr_out_enb <= do_out_y or do_out_cb or do_out_cr;