]> AND Private Git Repository - blast.git/blob - rgb3sx8_to_ycbcr_3DSP.vhd
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
correct bug with clkrstgen
[blast.git] / rgb3sx8_to_ycbcr_3DSP.vhd
1 -------------------------------------------------------------------------------
2 --
3 --  File          : rgb3sx8_to_ycbcr_3DSP.vhd
4 --  Related files : 
5 --
6 --  Author(s)     : stephane Domas (sdomas@univ-fcomte.fr)
7 --
8 --  Creation Date : 2017/10/16
9 --
10 --  Description   : This IP does a conversion from rgb24 (8 bits/serial) to YCrCb
11 --
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
16 --                  order: cb, cr, y
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
23 --
24 -------------------------------------------------------------------------------
25
26 library IEEE;
27 use IEEE.std_logic_1164.all;
28 use IEEE.numeric_std.all;
29
30 entity rgb3sx8_to_ycbcr_3DSP is
31   port(
32     clk           : in  std_logic;
33     reset         : in  std_logic;
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
38
39     );
40 end rgb3sx8_to_ycbcr_3DSP;
41
42
43 architecture rtl of rgb3sx8_to_ycbcr_3DSP is
44
45   component mult_accum
46     port (
47       clk    : in  std_logic;
48       ce     : in  std_logic;
49       sclr   : in  std_logic;
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)
54       );
55   end component;
56
57 -- Signals
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);
86
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);
99
100   signal compo_out : std_logic_vector(7 downto 0);
101
102 begin
103
104   y_multiplier : mult_accum
105     port map (
106       clk    => clk,
107       ce     => '1',
108       sclr   => '0',
109       bypass => bypass_y,
110       a      => a_y,
111       b      => b_y,
112       s      => s_y
113       );
114   cr_multiplier : mult_accum
115     port map (
116       clk    => clk,
117       ce     => '1',
118       sclr   => '0',
119       bypass => bypass_cr,
120       a      => a_cr,
121       b      => b_cr,
122       s      => s_cr
123       );
124   cb_multiplier : mult_accum
125     port map (
126       clk    => clk,
127       ce     => '1',
128       sclr   => '0',
129       bypass => bypass_cb,
130       a      => a_cb,
131       b      => b_cb,
132       s      => s_cb
133       );
134
135
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);
145
146   multy_process : process (clk, reset)
147   begin
148     if reset = '1' then
149       a_y <= (others => '0');
150       b_y <= (others => '0');
151
152       count_y  <= to_unsigned(0, 3);
153       do_sum_y <= '0';
154
155     elsif rising_edge(clk) then
156
157       do_sum_y <= '0';
158
159       a_y <= (others => '0');
160       b_y <= (others => '0');
161
162       if rgb_in_enb = '1' then
163
164         a_y <= "0000000000" & rgb_in;
165
166         if count_y = 0 then
167           b_y <= std_logic_vector(cst_y_b);
168
169           count_y <= to_unsigned(1, 3);
170
171         elsif count_y = 1 then
172           b_y     <= std_logic_vector(cst_y_g);
173           count_y <= to_unsigned(2, 3);
174
175         elsif count_y = 2 then
176           b_y      <= std_logic_vector(cst_y_r);
177           count_y  <= to_unsigned(0, 3);
178           do_sum_y <= '1';
179         end if;
180       end if;
181     end if;
182   end process multy_process;
183
184   sumy_process : process (clk, reset)
185   begin
186     if reset = '1' then
187       bypass_y <= '0';
188       y        <= to_signed(0, 9);
189       y_dly1   <= to_signed(0, 9);
190       y_dly2   <= to_signed(0, 9);
191
192     elsif rising_edge(clk) then
193       bypass_y     <= do_sum_y;
194       do_sum_y_dly <= do_sum_y;
195       y_dly1       <= y;
196       y_dly2       <= y_dly1;
197
198       if do_sum_y_dly = '1' then
199         y <= to_signed(16, 9) + signed(s_y(25 downto 17));
200       end if;
201     end if;
202
203   end process sumy_process;
204
205   multcb_process : process (clk, reset)
206   begin
207     if reset = '1' then
208       a_cb <= (others => '0');
209       b_cb <= (others => '0');
210
211       count_cb  <= to_unsigned(0, 3);
212       do_sum_cb <= '0';
213
214     elsif rising_edge(clk) then
215
216       do_sum_cb <= '0';
217
218       a_cb <= (others => '0');
219       b_cb <= (others => '0');
220
221       if rgb_in_enb = '1' then
222
223         a_cb <= "0000000000" & rgb_in;
224
225         if count_cb = 0 then
226           b_cb <= std_logic_vector(cst_cb_b);
227
228           count_cb <= to_unsigned(1, 3);
229
230         elsif count_cb = 1 then
231           b_cb     <= std_logic_vector(cst_cb_g);
232           count_cb <= to_unsigned(2, 3);
233
234         elsif count_cb = 2 then
235           b_cb      <= std_logic_vector(cst_cb_r);
236           count_cb  <= to_unsigned(0, 3);
237           do_sum_cb <= '1';
238         end if;
239       end if;
240     end if;
241   end process multcb_process;
242
243   sumcb_process : process (clk, reset)
244   begin
245     if reset = '1' then
246       bypass_cb <= '0';
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;
252       cb_dly1       <= cb;
253
254       if do_sum_cb_dly = '1' then
255         cb <= to_signed(128, 9) + signed(s_cb(25 downto 17));
256       end if;
257     end if;
258
259   end process sumcb_process;
260
261   multcr_process : process (clk, reset)
262   begin
263     if reset = '1' then
264       a_cr <= (others => '0');
265       b_cr <= (others => '0');
266
267       count_cr  <= to_unsigned(0, 3);
268       do_sum_cr <= '0';
269
270     elsif rising_edge(clk) then
271
272       do_sum_cr <= '0';
273
274       a_cr <= (others => '0');
275       b_cr <= (others => '0');
276
277       if rgb_in_enb = '1' then
278
279         a_cr <= "0000000000" & rgb_in;
280
281         if count_cr = 0 then
282           b_cr <= std_logic_vector(cst_cr_b);
283
284           count_cr <= to_unsigned(1, 3);
285
286         elsif count_cr = 1 then
287           b_cr     <= std_logic_vector(cst_cr_g);
288           count_cr <= to_unsigned(2, 3);
289
290         elsif count_cr = 2 then
291           b_cr      <= std_logic_vector(cst_cr_r);
292           count_cr  <= to_unsigned(0, 3);
293           do_sum_cr <= '1';
294         end if;
295       end if;
296     end if;
297   end process multcr_process;
298
299   sumcr_process : process (clk, reset)
300   begin
301     if reset = '1' then
302       bypass_cr <= '0';
303       cr        <= to_signed(0, 9);
304       do_out_cr    <= '0';
305
306     elsif rising_edge(clk) then
307       bypass_cr     <= do_sum_cr;
308       do_sum_cr_dly <= do_sum_cr;
309       do_out_cr        <= '0';
310
311       if do_sum_cr_dly = '1' then
312         do_out_cr <= '1';
313         cr     <= to_signed(128, 9) + signed(s_cr(25 downto 17));
314       end if;
315     end if;
316   end process sumcr_process;
317
318   out_process : process (clk, reset)
319   begin
320     if reset = '1' then
321       do_out_y    <= '0';
322       do_out_cb    <= '0';
323     elsif rising_edge(clk) then
324       do_out_cb <= do_out_cr;
325       do_out_y <= do_out_cb;
326     end if;
327   end process out_process;
328
329
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
333                    (others => '0');
334   ycbcr_out_enb <= do_out_y or do_out_cb or do_out_cr;
335
336 end rtl;
337