NTSC_TO_VGA_Converter_Presentation_2010_A[1]

advertisement
NTSC to VGA Converter
Marco Moreno
Adrian De La Rosa
EE382M-4 Adv Emb Arch
1
Project Goal
NTSC Video
Source
RCA
Video Cable
TLL5000
Spartan3 FPGA
15-pin VGA
Cable
2
Project Challenges
• YUV -> RGB color space conversion
• Input to display sync timing
• Interlaced video to progressive scan
Project Hardware
• TLL5000 – base development module
– Analog Devices: ADV7180 - NTSC decoder
– Analog Devices: ADV7125 - VGA DAC
– Xilinx: Spartan III - FPGA
• TLL6219 – MX21 daughter board
• Digital camera NTSC source + A/V cable
• LCD monitor + 15-pin VGA cable
4
ADV7180 NTSC Decoder
• Analog Input
– Composite
– Component
– Svideo
• Digital Outputs
– LLC 27MHz clock
– HS, VS/Field
– 8-bit Output Port P
5
ADV7180 Block Diagram
6
ADV7125 Video DAC
Converts 8-bit values on RGB
ports to analog levels for display
7
Color-Space Conversion
• YUV Data Format
• RGB Data Format
• Color-space conversion
• Conversion quality / speed
8
YUV Data Format
• Compatible with black & white TV
infrastructure
• U & V color difference signals.
• Single Image format
• Video format
9
YUV Analyzer
Sunray Image – YUV Tools
http://www.sunrayimage.com/
Analysis data used for conversion quality reference
10
RGB Data Format
• Additive color model
• R, G and B are color contributions rather than
color differences
• Single Image Format
• Video Format
– Three channels for color, 8-bit values
– VGA connector – separate lines for vertical and horizontal
synchronization signals.
11
Color-space conversion
R = 1.164*((int)Y - 16) + 1.596*((int)V - 128);
G = 1.164*((int)Y - 16) - 0.714*((int)V - 128) - 0.344*((int)U-128);
B = 1.164*((int)Y - 16) + 2.018*((int)U - 128);
• Multiple sources for
information
• Multiple recommendations
for values used in
calculation
• Ultimately chose a mix to
give values closed to
reference YUV tool
analyzer
12
Conversion C++ code
//memory allocation
int *yuv = (volatile unsigned int *)malloc(YUVBLOCK);
//Open the file for reading in binary format
int fd = open("flower_droplet.uyvy", O_RDWR);
//write file to yuv memory block
read(fd, yuv, YUVBLOCK);
close(fd);
//open file for writing
fd = open ("converted.bmp", O_CREAT|O_RDWR);
printf("fd %d\n", fd);
// write header
write(fd,&header[0],4);
.
.
.
write(fd,&header[13],2);
//Calculate values and store to array
R = 1.164*((int)Y - 16) + 1.596*((int)V - 128);
G = 1.164*((int)Y - 16) - 0.714*((int)V - 128) - 0.344*((int)U-128);
B = 1.164*((int)Y - 16) + 2.018*((int)U - 128);
•
•
•
•
•
Allocate memory
Open file and write to mem
Create new file
Write header for new file
Calculate all pixel RGB
data
• Write out to new file
• Rev 1.0 :~4hr
• Rev 2.0 : ~4sec
//Write entire array to memory at once
write(fd,&BLOCK[0],YUVBLOCK);
printf("\n\n");
close(fd);
13
Conversion Verilog code
• Implemented with shifts and adds only
• Asynchronous logic block
• Bitwise operations
// CALCULATE Y COMPONENT OF R, G AND B
assign ycomp = ((y & 8'hf0) == 8'h00) ? (8'h00 - y_16 - {3'b0, y_16[7:3]}) : ((y_16) + {3'b0, y_16[7:3]} + {5'b0, y_16[7:5]} + {7'b0, y_16[7]});
// CALCULATE V COMPONENT OF R
assign r_vcomp = ((v & 8'h80) == 8'h00) ? (9'd0 - v_128 - {3'b0, v_128[7:3]} - {4'b0, v_128[7:4]}) : (v_128 + {3'b0, v_128[7:3]} + {4'b0, v_128[7:4]});
// CALCULATE V COMPONENT OF G
assign g_vcomp = ((v & 8'h80) == 8'h00) ? (9'b0 - {1'b0, v_128[7:1]} - {3'b0, v_128[7:3]} - {4'b0, v_128[7:4]} - {5'b0, v_128[7:5]}) : ({1'b0, v_128[7:1]} + {3'b0, v_128[7:3]} + {4'b0, v_128[7:4]} + {5'b0,
v_128[7:5]});
// CALCULATE U COMPONENT OF G
assign g_ucomp = ((u & 8'h80) == 8'h00) ? (9'b0 - {2'b0, u_128[7:2]} - {4'b0, u_128[7:4]} - {5'b0, u_128[7:5]} - {6'b0, u_128[7:6]}) : ({2'b0, u_128[7:2]} + {4'b0, u_128[7:4]} + {5'b0, u_128[7:5]} + {6'b0,
u_128[7:6]});
// CALCULATE U COMPONENT OF B
assign b_ucomp = ((u & 8'h80) == 8'h00) ? (9'b0 - {u_128, 1'b0} - {6'b0, u_128[7:6]}) : ({u_128, 1'b0} + {6'b0, u_128[7:6]});
// ADD COMPONENTS TO CALCULATE R, G AND B
assign r_wire = ycomp + r_vcomp;
assign g_wire = ycomp - g_vcomp - g_ucomp;
assign b_wire = ycomp + b_ucomp;
// CHECK FOR R, G OR B LESS THAN ZERO
assign r_zero = (r_wire[8] && 1) ? (9'h00) : (r_wire);
assign g_zero = (g_wire[8] && 1) ? (9'h00) : (g_wire);
assign b_zero = (b_wire[8] && 1) ? (9'h00) : (b_wire);
// CHECK FOR R, G, OR B GREATER THAN 255 AND SET FINAL VALUE
assign r = (r_zero[8:7] > 255) ? (8'hff) : (r_zero[7:0]);
assign g = (g_zero[8:7] > 255) ? (8'hff) : (g_zero[7:0]);
assign b = (b_zero[8:7] > 255) ? (8'hff) : (b_zero[7:0]);
Y-component = (y - 16) * 1.0010101;
Y-component = (y - 16) + (Y - 16 ) >> 3 + (y - 16) >> 5 + (Y - 16) >> 7;
V-component of R = (V - 128) * 1.0011;
V-component of R = (V - 128) + (V - 128) >> 3 + (V - 128) >> 4;
V-component of G = (V - 128) * .10111
V-component of G = (V - 128) * (V - 128) >> 1 + (V - 128) >> 3 + (V - 128) >> 4
+ (V - 128) >> 5;
U-component of G = (U - 128) * .010111;
U-component of G = (U - 128) >> 2 + (U - 128) >> 4 + (U - 128) >> 5 + (U - 128)
>> 6;
U-component of B = (U - 128) * 10.000001;
U-component of B = (U - 128) << 1 + (U - 128) >> 6;
14
Conversion quality / speed
Pixels
Y
0x4b
V
0x7c
75
R
Ref.
C++
Verilog
Y
0x4b
124
G
62
62
63
U
0x67
75
B
82
80
76
18
18
17
103
Unoptimized C++ code
Rev 1.0 : ~ 4hr
Rev 2.0 : ~4sec
FPGA operating @ ~27Mhz pixel clock
Frame rate 60 Hz
One frame - ~16 msec
15
Video Synchronization
• NTSC to VGA timing generation
• Interlaced video to progressive scan
• Solution architecture
16
VGA Sync Signals
17
VGA Sync Timing (Typical)
Horizontal Regions
Vertical Regions
VGA mode
Resolution
(HxV)
Pixel clock(Mhz)
a(ms)
b(us)
c(us)
d(us)
a(lines)
b(lines)
c(lines)
d(lines)
VGA(60Hz)
640x480
25 (640/c)
3.8
1.9
25.4
0.6
2
33
480
10
VGA(85Hz)
640x480
36 (640/c)
1.6
2.2
17.8
1.6
3
25
480
1
SVGA(60Hz)
800x600
40 (800/c)
3.2
2.2
20
1
4
23
600
1
SVGA(75Hz)
800x600
49 (800/c)
1.6
3.2
16.2
0.3
3
21
600
1
SVGA(85Hz)
800x600
56 (800/c)
1.1
2.7
14.2
0.6
3
27
600
1
XGA(60Hz)
1024x768
65 (1024/c)
2.1
2.5
15.8
0.4
6
29
768
3
XGA(70Hz)
1024x768
75 (1024/c)
1.8
1.9
13.7
0.3
6
29
768
3
XGA(85Hz)
1024x768
95 (1024/c)
1.0
2.2
10.8
0.5
3
36
768
1
1280x1024(60Hz)
1280x1024
108 (1280/c)
1.0
2.3
11.9
0.4
3
38
1024
1
18
VGA Progressive Video
Line
Line
Line
Line
1
2
3
4
…
Line
Line
Line
Line
522
523
524
525
19
NTSC Interlaced Video
20
Field 2 start
(odd lines)
Generated VGA VSYNC
VS/Field (from NTSC decoder)
Generated VGA HSYNC
HS (from NTSC decoder)
Field 1 / Field 2 scanning
Field 1 start
(even lines)
21
De-Interlacing
22
Video Stream Architecture
RCA Input
ADV7180
NTSC Decoder
LLC - 27MHz pixel clock
VGA VSYNC
Generator
VGA VSYNC
VGA HSYNC
4:2:2
De-Interlace /
Pixel Reformat
4:4:4
Color Space
Converter
ADV7125
Video DAC
VGA Analog Color Channels
23
De-Interlace Line Buffers
WR_BUF_SEL
WR_BUF_SEL ? WR_PTR : RD_PTR
2 x RAMB16_S18
WE
ADDR[9:0]
DIN[15:0]
YUV 4:2:2
8-bits per clk
RD_BUF_SEL ? WR_PTR : RD_PTR
WR_BUF_SEL
DOUT[15:0]
1
DOUT[15:0]
0
YUV 4:4:4
16-bits per clk
DIN[15:0]
ADDR[9:0]
WE
RD_BUF_SEL
24
ADV7180 I2C Interface
–
–
–
–
Serial protocol for interconnecting IC’s
I2C block registers memory mapped to CPU
Linux mmap application command line interface
Controls various timing and format options
iMX.21
Registers
0xCC0000000xCC000100
Wishbone
FPGA I2C
Controller
SCLK
SDA
ADV7180
NTSC Decoder
Registers
-Input Select
-H/V SYNC shape
-Video Format
-Interrupt Control
25
Lessons Learned
• Keep Verilog code simple
• Edge triggers are extremely useful
• Tie one-off possibilities to switches
• Not all TLL5000 boards have same clocks
26
Potential future work
• Complete optimization of C++ code
• Implement video stream with ARM
controller rather than full-fpga
implementation
• FPGA vs. ARM performance analysis
• FPGA vs. ARM power analysis
• Fix horizontal positioning error
• Smooth de-interlace w/ interpolation
• DMA image data to iMX.21 SDRAM
27
Backup
28
Hsync generation
29
Vsync generation
30
Field 1 / 2 & data transmission
31
Direct Y-data NTSC to VGA
32
RGB channel separation
33
Buffered, CSC, Partially Aligned
34
Download