1 -------------------------------------------------------------------------------
2 -- Title : YCbCr to RGB converter
3 -- Project : theora-fpga
4 -------------------------------------------------------------------------------
5 -- File : YCbCr2RGB.vhd
6 -- Author : Leonardo de Paula Rosa Piga
7 -- Company : LSC - IC - UNICAMP
8 -- Last update: 2007/08/23
10 -------------------------------------------------------------------------------
11 -- Description: A YCbCr to RGB converter
12 -------------------------------------------------------------------------------
17 use ieee.std_logic_1164.
all;
18 use ieee.numeric_std.
all;
23 DEPTH
: natural
:= 8192; -- RGB MEMORY DEPTH
24 ADDR_WIDTH
: natural
:= 13; -- RGB MEMORY ADDRESS WIDTH
25 DATA_WIDTH
: natural
:= 24; -- RGB MEMORY DATA WIDTH
26 ZOOM
: natural
range 0 to 7 := 4 -- Image will be scaled to ZOOM
30 reset_n
: in std_logic;
32 ---------------------------------------------------------------------------
34 ---------------------------------------------------------------------------
35 in_request
: out std_logic;
36 in_valid
: in std_logic;
37 in_data
: in signed
(31 downto 0);
39 ---------------------------------------------------------------------------
40 -- Ports of RGB frame memory
41 ---------------------------------------------------------------------------
42 rgb_rd_addr
: in unsigned
(ADDR_WIDTH
-1 downto 0);
43 rgb_rd_data
: out signed
(DATA_WIDTH
-1 downto 0);
45 ---------------------------------------------------------------------------
46 -- Port of RGB frame memory control access
47 ---------------------------------------------------------------------------
48 can_read_mem
: out std_logic
54 architecture a_YCbCr2RGB
of YCbCr2RGB
is
58 DEPTH
: positive
:= 64; -- How many slots
59 DATA_WIDTH
: positive
:= 16; -- How many bits per slot
60 ADDR_WIDTH
: positive
:= 6 -- = ceil(log2(DEPTH))
66 wr_addr
: in unsigned
(ADDR_WIDTH
-1 downto 0);
67 wr_data
: in signed
(DATA_WIDTH
-1 downto 0);
68 rd_addr
: in unsigned
(ADDR_WIDTH
-1 downto 0);
69 rd_data
: out signed
(DATA_WIDTH
-1 downto 0)
71 end component tsyncram
;
73 -----------------------------------------------------------------------------
74 -- Signals of Master State Machine
75 -----------------------------------------------------------------------------
76 type state_t
is (stt_clean_buffers
,
81 signal state
: state_t
;
85 -----------------------------------------------------------------------------
86 -- Signals of ReadIn procedure
87 -----------------------------------------------------------------------------
88 type read_state_t
is (stt_read_height
,
94 signal read_state
: read_state_t
;
96 -----------------------------------------------------------------------------
97 -- Signals of ReadMemConvert procedure
98 -----------------------------------------------------------------------------
99 type conv_readmem_state_t
is (stt_conv_readmem1
,
108 signal conv_readmem_state
: conv_readmem_state_t
;
110 signal val_Y
, val_Cb
, val_Cr
: unsigned
(7 downto 0);
112 -----------------------------------------------------------------------------
113 -- Signals of WriteMemConvert procedure
114 -----------------------------------------------------------------------------
115 type conv_writemem_state_t
is (stt_conv_writemem1
,
122 signal conv_writemem_state
: conv_writemem_state_t
;
124 signal val_red
, val_green
, val_blue
: signed
(31 downto 0);
126 -----------------------------------------------------------------------------
127 -- Signals of BufferAccessControl process
128 -----------------------------------------------------------------------------
129 type buf_access_state_t
is (stt_buf_access1
,
132 signal buf_access_state
: buf_access_state_t
;
133 signal repeat_line
: natural
range 0 to 7;
135 -----------------------------------------------------------------------------
136 -- Buffer memories parameters
137 -----------------------------------------------------------------------------
138 constant MEM_Y_DEPTH
: natural
:= 2048;
139 constant MEM_Y_DATA_WIDTH
: natural
:= 32;
140 constant MEM_Y_ADDR_WIDTH
: natural
:= 11;
143 constant MEM_DEPTH
: natural
:= 512;
144 constant MEM_DATA_WIDTH
: natural
:= 32;
145 constant MEM_ADDR_WIDTH
: natural
:= 9;
148 constant MEM_RGB_DEPTH
: natural
:= DEPTH
;
149 constant MEM_RGB_DATA_WIDTH
: natural
:= DATA_WIDTH
;
150 constant MEM_RGB_ADDR_WIDTH
: natural
:= ADDR_WIDTH
;
152 constant MAX_SIZE
: natural
:= 1023;
153 constant LG2_MAX_SIZE
: natural
:= 10;
154 -----------------------------------------------------------------------------
155 -- signals of Y memory
156 -----------------------------------------------------------------------------
157 signal mem_Y_wr_e
: std_logic;
158 signal mem_Y_wr_addr
: unsigned
(MEM_Y_ADDR_WIDTH
-1 downto 0);
159 signal mem_Y_wr_data
: signed
(MEM_Y_DATA_WIDTH
-1 downto 0);
160 signal mem_Y_rd_addr
: unsigned
(MEM_Y_ADDR_WIDTH
-1 downto 0);
161 signal mem_Y_rd_data
: signed
(MEM_Y_DATA_WIDTH
-1 downto 0);
163 -----------------------------------------------------------------------------
164 -- signals of Cb memory
165 -----------------------------------------------------------------------------
166 signal mem_Cb_wr_e
: std_logic;
167 signal mem_Cb_wr_addr
: unsigned
(MEM_ADDR_WIDTH
-1 downto 0);
168 signal mem_Cb_wr_data
: signed
(MEM_DATA_WIDTH
-1 downto 0);
169 signal mem_Cb_rd_addr
: unsigned
(MEM_ADDR_WIDTH
-1 downto 0);
170 signal mem_Cb_rd_data
: signed
(MEM_DATA_WIDTH
-1 downto 0);
172 -----------------------------------------------------------------------------
173 -- signals of Cr memory
174 -----------------------------------------------------------------------------
175 signal mem_Cr_wr_e
: std_logic;
176 signal mem_Cr_wr_addr
: unsigned
(MEM_ADDR_WIDTH
-1 downto 0);
177 signal mem_Cr_wr_data
: signed
(MEM_DATA_WIDTH
-1 downto 0);
178 signal mem_Cr_rd_addr
: unsigned
(MEM_ADDR_WIDTH
-1 downto 0);
179 signal mem_Cr_rd_data
: signed
(MEM_DATA_WIDTH
-1 downto 0);
181 -----------------------------------------------------------------------------
182 -- signals of RGB memory
183 -----------------------------------------------------------------------------
184 signal mem_RGB_wr_e
: std_logic;
185 signal mem_RGB_wr_addr
: unsigned
(MEM_RGB_ADDR_WIDTH
-1 downto 0);
186 signal mem_RGB_wr_data
: signed
(MEM_RGB_DATA_WIDTH
-1 downto 0);
187 signal mem_RGB_rd_addr
: unsigned
(MEM_RGB_ADDR_WIDTH
-1 downto 0);
188 signal mem_RGB_rd_data
: signed
(MEM_RGB_DATA_WIDTH
-1 downto 0);
190 signal mem_Y_cleaned
: std_logic;
191 signal mem_Cr_cleaned
: std_logic;
192 signal mem_Cb_cleaned
: std_logic;
193 signal mem_RGB_cleaned
: std_logic;
196 signal first_clean
: std_logic;
197 signal first_write
: std_logic;
198 signal half_left_half_right
: std_logic; -- '0' if we will choose the left
199 -- half of Cb and Cr pixels of one
202 signal s_in_request
: std_logic;
204 signal can_write_mem
: std_logic;
205 signal new_frame
: std_logic;
207 signal mem_read_line
: integer range 0 to 1023;
208 signal mem_read_col
: integer range 0 to 1023;
209 signal counter_cols
, counter_lines
: integer range 0 to 1023;
211 -----------------------------------------------------------------------------
212 -- Video parameter signals
213 -----------------------------------------------------------------------------
214 signal video_width
, video_height
: integer range 0 to 1023;
217 mem_RGB_rd_addr
<= rgb_rd_addr
;
218 rgb_rd_data
<= mem_RGB_rd_data
;
220 can_read_mem
<= '0' when state
= stt_clean_buffers
else
221 '0' when read_state
= stt_read_width
else
222 '0' when read_state
= stt_read_height
else
225 mem_Y_plane
: tsyncram
227 DEPTH
=> MEM_Y_DEPTH
,
228 DATA_WIDTH
=> MEM_Y_DATA_WIDTH
,
229 ADDR_WIDTH
=> MEM_Y_ADDR_WIDTH
)
233 wr_addr
=> mem_Y_wr_addr
,
234 wr_data
=> mem_Y_wr_data
,
235 rd_addr
=> mem_Y_rd_addr
,
236 rd_data
=> mem_Y_rd_data
);
238 mem_Cb_plane
: tsyncram
241 DATA_WIDTH
=> MEM_DATA_WIDTH
,
242 ADDR_WIDTH
=> MEM_ADDR_WIDTH
)
246 wr_addr
=> mem_Cb_wr_addr
,
247 wr_data
=> mem_Cb_wr_data
,
248 rd_addr
=> mem_Cb_rd_addr
,
249 rd_data
=> mem_Cb_rd_data
);
251 mem_Cr_plane
: tsyncram
254 DATA_WIDTH
=> MEM_DATA_WIDTH
,
255 ADDR_WIDTH
=> MEM_ADDR_WIDTH
)
259 wr_addr
=> mem_Cr_wr_addr
,
260 wr_data
=> mem_Cr_wr_data
,
261 rd_addr
=> mem_Cr_rd_addr
,
262 rd_data
=> mem_Cr_rd_data
);
266 DEPTH
=> MEM_RGB_DEPTH
,
267 DATA_WIDTH
=> MEM_RGB_DATA_WIDTH
,
268 ADDR_WIDTH
=> MEM_RGB_ADDR_WIDTH
)
271 wr_e
=> mem_RGB_wr_e
,
272 wr_addr
=> mem_RGB_wr_addr
,
273 wr_data
=> mem_RGB_wr_data
,
274 rd_addr
=> mem_RGB_rd_addr
,
275 rd_data
=> mem_RGB_rd_data
);
278 in_request
<= s_in_request
;
280 -- purpose: Verify if the RGB buffer was written before overwrite it
282 -- inputs : clk, reset_n
283 -- outputs: can_write_mem
284 BufferAccessControl
: process (clk
, reset_n
)
285 begin -- process BufferAccessControl
286 if (reset_n
) = '0' then -- asynchronous reset (active low)
287 can_write_mem
<= '1';
288 buf_access_state
<= stt_buf_access1
;
291 elsif clk
'event and clk
= '1' then -- rising clock edge
293 case buf_access_state
is
294 when stt_buf_access1
=>
295 if (new_frame
= '1') then
296 buf_access_state
<= stt_buf_access2
;
297 can_write_mem
<= '0';
299 when stt_buf_access2
=>
300 if (rgb_rd_addr
= video_height
* video_width
- 1) then
301 repeat_line
<= repeat_line
+ 1;
302 if (repeat_line
= ZOOM
- 1) then
304 buf_access_state
<= stt_buf_access1
;
305 can_write_mem
<= '1';
311 end process BufferAccessControl
;
315 -- purpose: Clean buffers, read width and height once and the frame in the YUV
316 -- format and convert the Buffer to the RGB representation
318 -- inputs : Clk, reset_n
319 Converter
: process (Clk
, reset_n
)
321 ---------------------------------------------------------------------------
322 -- Procedure that writes zero in all positions of all memories
323 ---------------------------------------------------------------------------
324 procedure CleanBuffers
is
327 mem_Y_wr_data
<= (others => '0');
330 mem_Cb_wr_data
<= (others => '0');
333 mem_Cr_wr_data
<= (others => '0');
336 mem_RGB_wr_data
<= (others => '0');
338 if (first_clean
= '1') then
340 mem_Y_wr_addr
<= (others => '0');
341 mem_Cb_wr_addr
<= (others => '0');
342 mem_Cr_wr_addr
<= (others => '0');
343 mem_RGB_wr_addr
<= (others => '0');
345 mem_Y_wr_addr
<= mem_Y_wr_addr
+ 1;
346 mem_Cb_wr_addr
<= mem_Cb_wr_addr
+ 1;
347 mem_Cr_wr_addr
<= mem_Cr_wr_addr
+ 1;
348 mem_RGB_wr_addr
<= mem_RGB_wr_addr
+ 1;
351 if ((mem_Y_wr_addr
= MEM_Y_DEPTH
- 1) or (mem_Y_cleaned
= '1')) then
353 mem_Y_cleaned
<= '1';
354 mem_Y_wr_addr
<= (others => '0');
357 if ((mem_Cb_wr_addr
= MEM_DEPTH
- 1) or (mem_Cb_cleaned
= '1')) then
359 mem_Cb_cleaned
<= '1';
360 mem_Cb_wr_addr
<= (others => '0');
363 if ((mem_Cr_wr_addr
= MEM_DEPTH
- 1) or (mem_Cr_cleaned
= '1')) then
365 mem_Cr_cleaned
<= '1';
366 mem_Cr_wr_addr
<= (others => '0');
369 if ((mem_RGB_wr_addr
= MEM_RGB_DEPTH
- 1) or (mem_RGB_cleaned
= '1')) then
371 mem_RGB_cleaned
<= '1';
372 mem_RGB_wr_addr
<= (others => '0');
375 if (mem_Y_cleaned
= '1' and mem_Cb_cleaned
= '1' and
376 mem_Cr_cleaned
= '1' and mem_RGB_cleaned
= '1') then
377 mem_Y_cleaned
<= '0';
378 mem_Cb_cleaned
<= '0';
379 mem_Cr_cleaned
<= '0';
380 mem_RGB_cleaned
<= '0';
381 read_state
<= stt_read_Y
;
384 end procedure CleanBuffers
;
390 if (s_in_request
= '1' and in_valid
= '1') then
392 when stt_read_height
=>
393 video_height
<= to_integer
(in_data
);
394 read_state
<= stt_read_width
;
396 when stt_read_width
=>
397 video_width
<= to_integer
(in_data
);
398 read_state
<= stt_read_Y
;
399 state
<= stt_clean_buffers
;
405 mem_Y_wr_data
<= in_data
;
406 mem_Y_wr_addr
<= resize
408 (to_unsigned
(video_width
*counter_lines
+ counter_cols
, MEM_Y_ADDR_WIDTH
+4)
409 , 2), MEM_Y_ADDR_WIDTH
);
411 counter_cols
<= counter_cols
+ 4;
412 if (counter_cols
= video_width
- 4) then -- if it is the last four pixels
414 counter_lines
<= counter_lines
+ 1;
415 if (counter_lines
= video_height
- 1) then
417 read_state
<= stt_read_Cb
;
424 mem_Cb_wr_data
<= in_data
;
425 mem_Cb_wr_addr
<= resize
427 (to_unsigned
((video_width
/2)*counter_lines
+ counter_cols
, MEM_ADDR_WIDTH
+4)
428 , 2), MEM_ADDR_WIDTH
);
431 counter_cols
<= counter_cols
+ 4;
432 if (counter_cols
= to_integer
(SHIFT_RIGHT
(to_unsigned
(video_width
, LG2_MAX_SIZE
), 1)) - 4) then -- if it is the last four pixels
434 counter_lines
<= counter_lines
+ 1;
435 if (counter_lines
= (to_integer
(SHIFT_RIGHT
(to_unsigned
(video_height
, LG2_MAX_SIZE
), 1))- 1)) then
437 read_state
<= stt_read_Cr
;
445 mem_Cr_wr_data
<= in_data
;
446 mem_Cr_wr_addr
<= resize
448 (to_unsigned
((video_width
/2)*counter_lines
+ counter_cols
, MEM_ADDR_WIDTH
+4)
449 , 2), MEM_ADDR_WIDTH
);
452 counter_cols
<= counter_cols
+ 4;
453 if (counter_cols
= to_integer
(SHIFT_RIGHT
(to_unsigned
(video_width
, LG2_MAX_SIZE
), 1)) - 4) then -- if it is the last four pixels
455 counter_lines
<= counter_lines
+ 1;
456 if (counter_lines
= (to_integer
(SHIFT_RIGHT
(to_unsigned
(video_height
, LG2_MAX_SIZE
), 1))- 1)) then
460 read_state
<= stt_read_Y
;
462 state
<= stt_conv_readmem
;
463 conv_readmem_state
<= stt_conv_readmem1
;
469 end procedure ReadIn
;
471 -- purpose: Read the Y, Cb and Cr memory and move to stt_conv_writedmem
472 procedure ReadMemConvert
is
473 variable v_addr_Y
, v_addr_CbCr
: unsigned
(19 downto 0);
474 begin -- ReadMemConvert
475 if (can_write_mem
= '1') then -- If the frame has benn already displayed
476 case conv_readmem_state
is
477 when stt_conv_readmem1
=>
478 v_addr_Y
:= to_unsigned
(mem_read_line
* video_width
+ mem_read_col
, 20);
479 v_addr_CbCr
:= resize
(SHIFT_RIGHT
(to_unsigned
(mem_read_line
, 10), 1) *
480 SHIFT_RIGHT
(to_unsigned
(video_width
, 10), 1) +
481 SHIFT_RIGHT
(to_unsigned
(mem_read_col
, 10), 1), 20);
483 mem_Y_rd_addr
<= resize
(SHIFT_RIGHT
(v_addr_Y
, 2), MEM_Y_ADDR_WIDTH
);
484 mem_Cb_rd_addr
<= resize
(SHIFT_RIGHT
(v_addr_CbCr
, 2), MEM_ADDR_WIDTH
);
485 mem_Cr_rd_addr
<= resize
(SHIFT_RIGHT
(v_addr_CbCr
, 2), MEM_ADDR_WIDTH
);
486 conv_readmem_state
<= stt_conv_readmem2
;
487 half_left_half_right
<= '0';
490 when stt_conv_readmem2
=>
491 -- Just wait for the memory delay
492 conv_readmem_state
<= stt_conv_readmem3
;
494 when stt_conv_readmem3
=>
495 val_Y
<= unsigned
(mem_Y_rd_data
(31 downto 24));
496 if (half_left_half_right
= '0') then
497 val_Cb
<= unsigned
(mem_Cb_rd_data
(31 downto 24));
498 val_Cr
<= unsigned
(mem_Cr_rd_data
(31 downto 24));
500 val_Cb
<= unsigned
(mem_Cb_rd_data
(15 downto 8));
501 val_Cr
<= unsigned
(mem_Cr_rd_data
(15 downto 8));
503 -- Move to stt_conv_writemem to convert to RGB and write the memory
504 state
<= stt_conv_writemem
;
505 conv_writemem_state
<= stt_conv_writemem1
;
507 -- When return from stt_conv_writemem mo to the next conv_readmem_state
508 conv_readmem_state
<= stt_conv_readmem4
;
510 when stt_conv_readmem4
=>
511 val_Y
<= unsigned
(mem_Y_rd_data
(23 downto 16));
512 if (half_left_half_right
= '0') then
513 val_Cb
<= unsigned
(mem_Cb_rd_data
(31 downto 24));
514 val_Cr
<= unsigned
(mem_Cr_rd_data
(31 downto 24));
516 val_Cb
<= unsigned
(mem_Cb_rd_data
(15 downto 8));
517 val_Cr
<= unsigned
(mem_Cr_rd_data
(15 downto 8));
519 -- Move to stt_conv_writemem to convert to RGB and write the memory
521 state
<= stt_conv_writemem
;
522 conv_writemem_state
<= stt_conv_writemem1
;
524 -- When return from stt_conv_writemem mo to the next conv_readmem_state
525 conv_readmem_state
<= stt_conv_readmem5
;
528 when stt_conv_readmem5
=>
529 val_Y
<= unsigned
(mem_Y_rd_data
(15 downto 8));
530 if (half_left_half_right
= '0') then
531 val_Cb
<= unsigned
(mem_Cb_rd_data
(23 downto 16));
532 val_Cr
<= unsigned
(mem_Cr_rd_data
(23 downto 16));
534 val_Cb
<= unsigned
(mem_Cb_rd_data
(7 downto 0));
535 val_Cr
<= unsigned
(mem_Cr_rd_data
(7 downto 0));
537 -- Move to stt_conv_writemem to convert to RGB and write the memory
539 state
<= stt_conv_writemem
;
540 conv_writemem_state
<= stt_conv_writemem1
;
542 -- When return from stt_conv_writemem mo to the next conv_readmem_state
543 conv_readmem_state
<= stt_conv_readmem6
;
545 when stt_conv_readmem6
=>
546 val_Y
<= unsigned
(mem_Y_rd_data
(7 downto 0));
547 if (half_left_half_right
= '0') then
548 val_Cb
<= unsigned
(mem_Cb_rd_data
(23 downto 16));
549 val_Cr
<= unsigned
(mem_Cr_rd_data
(23 downto 16));
551 val_Cb
<= unsigned
(mem_Cb_rd_data
(7 downto 0));
552 val_Cr
<= unsigned
(mem_Cr_rd_data
(7 downto 0));
554 -- Move to stt_conv_writemem to convert to RGB and write the memory
556 state
<= stt_conv_writemem
;
557 conv_writemem_state
<= stt_conv_writemem1
;
559 -- When return from stt_conv_writemem mo to the next conv_readmem_state
560 conv_readmem_state
<= stt_conv_readmem7
;
563 when stt_conv_readmem7
=>
564 half_left_half_right
<= not half_left_half_right
;
566 -- Prepare to request another address
567 conv_readmem_state
<= stt_conv_readmem8
;
569 mem_read_col
<= mem_read_col
+ 4;
570 if (mem_read_col
= video_width
- 4) then -- if it is the last pixel
572 mem_read_line
<= mem_read_line
+ 1;
574 if (mem_read_line
= video_height
- 1) then
578 assert false
report "YCbCr2RGB done"
severity NOTE
;
580 -- Can read another frame then move to read state
581 conv_readmem_state
<= stt_conv_readmem1
;
583 read_state
<= stt_read_Y
;
587 when stt_conv_readmem8
=>
588 -- Request another address
589 v_addr_Y
:= to_unsigned
(mem_read_line
* video_width
+ mem_read_col
, 20);
590 v_addr_CbCr
:= resize
(SHIFT_RIGHT
(to_unsigned
(mem_read_line
, 10), 1) *
591 SHIFT_RIGHT
(to_unsigned
(video_width
, 10), 1) +
592 SHIFT_RIGHT
(to_unsigned
(mem_read_col
, 10), 1), 20);
594 mem_Y_rd_addr
<= resize
(SHIFT_RIGHT
(v_addr_Y
, 2), MEM_Y_ADDR_WIDTH
);
595 mem_Cb_rd_addr
<= resize
(SHIFT_RIGHT
(v_addr_CbCr
, 2), MEM_ADDR_WIDTH
);
596 mem_Cr_rd_addr
<= resize
(SHIFT_RIGHT
(v_addr_CbCr
, 2), MEM_ADDR_WIDTH
);
597 conv_readmem_state
<= stt_conv_readmem2
;
602 -- purpose: Do YCbCr convertion and write data to the memory
603 procedure WriteMemConvert
is
604 begin -- WriteMemConvert
605 case conv_writemem_state
is
606 when stt_conv_writemem1
=>
607 val_red
<= resize
(to_signed
(1220542, 22) * (signed
('0' & val_Y) - 16), 32);
608 val_green <= resize(to_signed(1220542, 22) * (signed('0' &val_Y
) - 16), 32);
609 val_blue
<= resize
(to_signed
(1220542, 22) * (signed
('0' &val_Y) - 16), 32);
610 conv_writemem_state <= stt_conv_writemem2;
612 when stt_conv_writemem2 =>
613 val_red <= val_red + to_signed(1673527, 22) * (signed('0' & val_Cr
) - 128);
614 val_green
<= val_green
- to_signed
(852492, 22) * (signed
('0' &val_Cr) - 128);
615 val_blue <= val_blue + to_signed(2114978, 23) * (signed('0' &val_Cb
) - 128);
616 conv_writemem_state
<= stt_conv_writemem3
;
618 when stt_conv_writemem3
=>
619 val_green
<= val_green
- to_signed
(411042, 22) *(signed
('0' &val_Cb) - 128);
620 conv_writemem_state <= stt_conv_writemem4;
623 when stt_conv_writemem4 =>
624 val_red <= SHIFT_RIGHT(val_red , 20);
625 val_green <= SHIFT_RIGHT(val_green , 20);
626 val_blue <= SHIFT_RIGHT(val_blue , 20);
627 conv_writemem_state <= stt_conv_writemem5;
630 when stt_conv_writemem5 =>
632 if (val_red < 0) then
633 val_red(7 downto 0) <= x"00";
634 elsif (val_red > 255) then
635 val_red(7 downto 0) <= x"ff";
638 if (val_green < 0) then
639 val_green(7 downto 0) <= x"00";
640 elsif (val_green > 255) then
641 val_green(7 downto 0) <= x"ff";
644 if (val_blue < 0) then
645 val_blue(7 downto 0) <= x"00";
646 elsif (val_blue > 255) then
647 val_blue(7 downto 0) <= x"ff";
649 conv_writemem_state <= stt_conv_writemem6;
651 when stt_conv_writemem6 =>
654 mem_RGB_wr_data <= val_red(7 downto 0) & val_green(7 downto 0) & val_blue(7 downto 0);
656 if (first_write = '1') then
657 mem_RGB_wr_addr <= (others => '0');
659 mem_RGB_wr_addr <= mem_RGB_wr_addr + 1;
660 if (mem_RGB_wr_addr = video_height * video_width - 1) then
661 mem_RGB_wr_addr <= (others => '0');
665 conv_writemem_state <= stt_conv_writemem1;
666 state <= stt_conv_readmem;
670 begin -- process Converter
671 if reset_n = '0' then -- asynchronous reset (active low)
673 conv_readmem_state <= stt_conv_readmem1;
674 read_state <= stt_read_height;
677 mem_Y_wr_addr <= (others => '0');
678 mem_Y_wr_data <= (others => '0');
679 mem_Y_rd_addr <= (others => '0');
680 mem_Y_cleaned <= '0';
683 mem_Cb_wr_addr <= (others => '0');
684 mem_Cb_wr_data <= (others => '0');
685 mem_Cb_rd_addr <= (others => '0');
686 mem_Cb_cleaned <= '0';
689 mem_Cr_wr_addr <= (others => '0');
690 mem_Cr_wr_data <= (others => '0');
691 mem_Cr_rd_addr <= (others => '0');
692 mem_Cr_cleaned <= '0';
695 mem_RGB_wr_addr <= (others => '0');
696 mem_RGB_wr_data <= (others => '0');
697 mem_RGB_cleaned <= '0';
700 half_left_half_right <= '0';
704 elsif Clk'event and Clk = '1' then -- rising clock edge
708 when stt_clean_buffers => CleanBuffers;
709 when stt_read => ReadIn;
710 when stt_conv_readmem => ReadMemConvert;
711 when stt_conv_writemem => WriteMemConvert;
717 end process Converter;