Tải bản đầy đủ (.pdf) (18 trang)

ĐỒ ÁN CƠ SỞ Nghiên cứu VGA và xây dựng ứng dụng trên kit UP2_5 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (778.46 KB, 18 trang )

ĐỒ ÁN CƠ SỞ
Nghiên cứu VGA và xây dựng ứng
dụng trên kit UP2

2. KHỐI XỬ LÝ ẢNH YUV
2.1 SƠ ĐỒ KHỐI

Hình 10.1: Sơ đồ của khối xử lý ảnh YUV
Tên Mô tả
CLK
Xung clock 27Mhz từ kit DE2.
RESET Reset hệ thống.
mYCbCr_d[15:0] Dữ liệu hình ảnh ngõ vào.
oRequest
Tín hiệu điều khiển do VGA Controller cung
cấp: yêu cầu xuất dữ liệu.
iX[0]
Tín hiệu điều khiển do VGA Controller cung
cấp, cho biết vị trí của Pixel l chẵn hay lẻ (bit 0
trong gi trị của bộ đếm vị trí Pixel)
oRequest
Tín hiệu điều khiển do VGA Controller cung
cấp: yu cầu xuất dữ liệu.
iYCbCr Pixel ảnh sau qua Image Process xử lý.
oY[7:0]
Thành phần độ sáng (Luma) của Pixel được
tách ra.
oCb[7:0] Thành phần Cb của Pixel được tách ra.
oCr[7:0] Thành phần Cr của Pixel được tách ra.
Resgister[1 9][15:0]



9 thanh ghi tương ứng với cửa sổ 3x3 pixels.

2.2 MÔ TẢ
Khối Line Buffer: là bộ đệm để lưu lại các giá trị các Pixel cần thiết. Xét cửa
sổ 3x3 Pixel: trong chuỗi dữ liệu ngõ vào vị trí các pixel này như sau:

Để cửa pixel này xuất hiện cùng lúc trong 1 cửa sổ thì phải cần có các bộ
đệm ( các thanh ghi và line buffer) để lưu lại các giá trị của P1, P2, P3, P4, P5, P6,
P7, P8 cho đến khi P9 xuất hiện:

Hình 10.2: sử dụng các Line_Buferr và Regitster để tạo cửa sổ 3x3 pixel
Line_Buffer có thể là 1 FIFO hoặc là 1 thanh ghi dịch(shift register), nhưng
trong thư viện của Quartus không có FIFO với chiều dài 640 Words, nên ta sử
dụng thanh ghi dịch:
Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo
custom mới, đặt tên là Line_Buffer, chọn phần Memory Compiler >> shift register
( RAM-Based). Ta chọn độ rộng dữ liệu là 8bits, chiều dài (distance between Taps)
là 640, số Tap là 1, và đánh dấu chọn để sử dụng chân clock enable. Như vậy ta
được cửa sổ Pixel:

Khối xử lý ảnh: Ta chọn 1 trong hai chế độ làm việc: lọc trung bình và tách
biên.
 Lọc trung bình: Thực hiện phép tương quan cửa sổ pixel với mặt nạ

Tuy nhiên dữ liệu vào là 16 bit với 8 bit cao là thành phần Y và 8 bit thấp là
Cb hoặc Cr. Nên ta sử dụng khai báo để tách ra từng thành phần rồi xử lý:
Loc_trung_binh Loc_trung_binh_0 ( clock,
reset,
register1[7:0],

register2[7:0],
register3[7:0],
register4[7:0],
register5[7:0],
register6[7:0],
register7[7:0],
register8[7:0],
register9[7:0],
out2
);
Loc_trung_binh Loc_trung_binh_1 ( clock,
reset,
register1[15:8],
register2[15:8],
register3[15:8],
register4[15:8],
register5[15:8],
register6[15:8],
register7[15:8],
register8[15:8],
register9[15:8],
out1
);
Để thực hiện phép tương quan giữa cửa sổ Pixel với mặt nạ lọc, ta tiến hành
theo các bước:
 Nhân các thành phần tương ứng của 2 cửa sổ lại với nhau: mặt nạ lọc
chỉ có các hệ số 1, 2, 4 (dễ thấy kết quả là các số 10 bit )
k = 1 thì giữ nguyên: multi_1 <= { 2'b00, register1};
k = 2 thì dịch trái 1 bit : multi_2 <= { 1'b0, register2,1’b0};
k = 4 thì dịch trái 2 bit: multi_5 <= { register5,1’b00};

 Lấy tổng các tích vừa tìm được (tổng này là 12 bit):
assign multi1 = multi_1 + multi_3 + multi_7 + multi_9;
assign multi2 = multi_2 + multi_4 + multi_6 + multi_8;
assign multi = multi1 + multi2 + multi_5;
 Chia tổng trên cho 16 tương đương với việc lấy 8 bit cao:
assign out = multi[11:4];
 Tách biên: Tương tự như trên ta cũng tách dữ liệu 16 bit ra từng
thành phần để xử lý với các bước thực hiện như sau:
a) Tính |G
x
| và |G
y
|: Chập ma trận cửa sổ 3×3 pixels ảnh của frame với
hai mặt nạ lọc theo phương pháp gradient với măt nạ lọc Prewitt :

Mặt nạ lọc chỉ có các hệ số 0, 1, 2 , -1 và -2 ( k =1, 2 đã xét ở phép lọc
trung bình)
k = 0 thì multi <= 0;
k =-1 thì lấy bù 2: multi = ~{3'b000,register} + 1;
k = -2 dịch trái 1 bit rồi lấy bù 2: multi =
~{2'b00,register,1'b0}+1;
Với register [7:0] nhân với số [1:0] -> số [9:0] thêm bit dấu thành số [11:0],
tức là 12 bits. Sau đó cộng tất cả các thành phần của cửa sổ thu được rồi lấy 8 bit
cao trong giá trị tuyệt đối ta có kết quả là |Gx| và |G y|
b) Tính giá trị ngõ ra của pixel theo cơng thức G =




+ 




Tính giá trị bình phương của G
x
và G
y
với bộ nhân từ thư viện của
Quartus:
Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo
custom mới, đặt tên là MULT2, chọn phần Arithmetic >> LPM_MULT. Chọn độ
rộng bit ngõ vào là 8 bit. Sau khi tổng hợp ta được một khối với khai báo như sau:
module MULT2 ( dataa,
datab,
result);
Để lấy phép bình phương ta nhập cùng một giá trị cho 2 ngõ vào dataa và
datab.
Dùng bộ lấy căn bậc 2 từ thư viện của Quartus để tính G từ tổng hai kết quả
trên:
Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo
custom mới, đặt tên là SQUARE, chọn phần Arithmetic >> ALTSQRT. Chọn độ
rộng bit ngõ vào là 16 bit.Sau khi tổng hợp ta được một khối với khai báo như sau
(trong đó radical là dữ liệu 17 bit ngõ vào, q là kết quả 9 bit của phép lấy căn, ta
không sử dụng chân remainder):
module SQUARE ( radical,
q,
remainder);
Thực chất khối xử lý ảnh chỉ là các cặp khối lọc biên, lọc trung bình được
ghép song song nhau. Mỗi khối trong cặp xử lý trên từng 8 bit dữ liệu, sau đó ghép
chúng lại với nhau (out3, out 4 tương tự là các ngõ ra của các khối lọc biên)

assign out_pixel = (!reset)? 16'b0 : out;
assign out = select_process? {out1,out2} : {out3,out4};
Khối sẽ xuất ra giá trị của pixel ảnh tương ứng với giá trị pixel ảnh nằm
chính giữa cửa sổ. Có 1 vấn đề được đặt ra ở đây là khi một frame vừa bắt đầu thì
cửa sổ chưa có đủ 9 Pixel nhưng bộ xử lý ảnh vẫn thực hiện lọc và xuất pixel sẽ
dẫn đến sai số ở biên ảnh. Đồng thời khối Image Process cần có 1 số chu kỳ xung
clock để xử lý xong ảnh. Tuy nhiên với 1 frame kích thước 640 x 480 thì các sai
lệch này có thể chấp nhận được.
Khối Extract YCrCb to Y, Cr, Cb : đơn giản chỉ là tách chuỗi dữ liệu 16 bit
dạng YCrCb liên tiếp ra 3 thành phần Y, Cr, Cb. Dựa vào tín hiệu iX[0] do VGA
controller đưa ra để biết vị trí của Pixel trong hàng là chẵn hay lẻ(16 bit này là
YCb hay là YCr):
if(iX[0])
{mY,mCr} <= iYCbCr;
else
{mY,mCb} <= iYCbCr;
Như vậy dữ liệu 16 bit ngõ vào đã được xử lý và tách ra 3 thành phần Y, Cr,
Cb.
3. KHỐI CONVERT YCRCB TO RGB
3.1 SƠ ĐỒ KHỐI

Hình 11.1: Sơ đồ của khối Convert YCrCb to RGB
Tên
Mô t



CLK

Xung clock 27Mhz từ kit DE2.

RESET
Reset h


th

ng.

iY[7:0]
Thành ph

n đ


sáng (Luma) c

a Pixel đư

c tách ra.

iCb[7:0]
Thành ph

n Cb c

a
Pixel đư

c tách ra.


iCr[7:0]
Thành ph

n Cr c

a Pixel đư

c tách ra.

Red[9:0]
Thành ph

n Red c

a Pixel tương

ng.


Green[9:0]
Thành ph

n Green c

a Pixel tương

ng.


Blue[9:0]

Thành ph

n Blue c

a Pixel tương

ng.

3.2 MÔ TẢ
Khối này chuyển đổi từ dạng dữ liệu ảnh YCrCb 8 bit sang dạng RGB 10 bit
cho phù hợp với yêu cầu ngõ vào của VGA DAC là ADV7123. Dưới đây là công
thức chuyển đổi sang dạng RGB 8 bit:
R = 1.164 ( Y - 16 ) + 1.596 ( Cr – 128 ) ;
G = 1.164 ( Y - 16) - 0.392 ( Cb - 128 ) - 0.813 ( Cr - 128 ) ;
B = 1.164 ( Y - 16 ) + 2.017 ( Cb – 128 ) ;
Sau đó để có dạng RGB 10 bit thì ta dịch trái 2 bit ( nhân 4 ) nên có công
thức mới:
R’ = 4.656 ( Y - 16 ) + 6.384 ( Cr - 128 ) ;
G’ = 4.656 ( Y - 16 ) - 1.568 ( Cb - 128 ) - 3.252 ( Cr - 128 );
B’ = 4.656 ( Y - 16 ) + 8.068 ( Cb - 128 ) ;
Do các hệ số có dạng thập phân, trong khi đó các phép toán của phần cứng
được tổng hợp chỉ thực hiện trên số nguyên nên khi làm tròn và tính toán thì sai số
khá lớn, vì vậy ta phải nhân biểu thức trên với một số nguyên H nào đó để giảm
bớt sai số khi làm tròn các hệ số, sau đó tính toán biểu thức rồi chia lại cho H. Số
nguyên H ta chọn có dạng 2
k
thì thay vì thực hiện phép chia cho A ta chỉ cần dịch
phải k bit. Ở đây ta chọn k = 7 hay H = 128 thì đô chính xác của hệ số sẽ đến chữ
số thứ 2 sau dấu phẩy. Ta có công thức cuối cùng (đã làm tròn để tính toán trên các
số nguyên) :

oR = (596 Y + 817Cr – 114131) : 128 ;
oG = (596 Y – 200Cb – 416Cr + 69370) : 128 ;
oB = (596 Y + 1033Cb – 141781) : 128 ;
Để thực hiện công thức trên ta tiến hành theo các bước:
 Nhân các thành phần Y, Cb, Cr với các hệ số tương ứng rồi cộng
chúng lại, sử dụng bộ tổng hợp cộng nhân ( ALTMULT_ADD ) trong thư viện của
Quartus :
Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo
custom mới, đặt tên là MAC3; chọn phần Arithmetic>>ALTMULT_ADD. Với các
thông số được chọn như sau:
- Tính oG cần 3 phép nhân : số lượng bộ nhân là 3.
- Y,Cb,Cr là số 8 bit dương: độ rộng ngõ vào A là 8, kiểu dữ liệu không
dấu (Unsigned)
- Trong các hệ số có số âm nên, giá trị lớn nhất là 1033 (số 11 bit) : độ
rộng ngõ vào B là 11, kiểu dữ liệu có dấu (signed)
- Chọn hàm giữa hai bộ nhân đầu tiên (first pair of multiplier) là phép
cộng (Add). Khi tổng hợp xong ta được một khối với khai báo như sau :
module MAC_3 ( dataa_0,
dataa_1,
dataa_2,
datab_0,
datab_1,
datab_2,
result,
aclr0,
clock0);
Trong đó:
- Ngõ vào điều khiển : xóa bất đồng bộ aclr0 và xung clock làm việc
clock0.
- Các ngõ vào dữ liệu là dataa_0; dataa_1; dataa_2 là các số 7 bit không

dấu; datab_0; datab_1; datab_2 là các số 11 bit có dấu;
- Ngõ ra là dữ liệu 21 bit có dấu:
result = (dataa_0 × datab_0) + (dataa_1 × datab_1) + (dataa_2 ×
datab_2).
Chú ý: data_b0, data_b1, data_b2 là các hệ số ở công thức đã tính ở trên:
596
d
= 254
h
, 817
d
= 331
h
, -200
d
= F38
h
(số bù hai), -416
d
= E60
h
(số bù hai), 1033
d

= 409
h
.Vậy để thực hiện bước này ta sẽ gọi các khối MAC_3 như sau:
MAC_3 u0( iY, iCb, iCr,
11'h254, 11'h000, 11'h331,
X, iRESET, iCLK);

MAC_3 u1( iY, iCb, iCr,
11'h254, 11'hF38, 11'hE60,
Y, iRESET, iCLK);
MAC_3 u2( iY, iCb, iCr,
11'h254, 11'h409, 11'h000,
Z, iRESET, iCLK);
Sau đó trừ (cộng) với các số hạng còn lại rồi chia cho 128 bằng cách dịch
phải 7 bit:
X_OUT <= ( X - 114131 ) >>7;
Y_OUT <= ( Y + 69370 ) >>7;
Z_OUT <= ( Z - 141787 ) >>7;
Tuy nhiên khi các giá trị R, G, B được tính theo công thức trên thì có thể là
số âm hoặc vượt quá 1023 (10 bit ) vì vậy ta giới hạn lại giá trị vào trong khoảng 0
đến 1023:
if(X_OUT[13])
oRed<=0;
else if(X_OUT[12:0]>1023)
oRed<=1023;
Thực hiện tương tự với 2 thành phần còn lại thì dữ liệu khối xuất ra sẽ là
dạng RGB phù hợp với yêu cầu đặt ra.
4. KHỐI VGA CONTROLLER
4.1 SƠ ĐỒ KHỐI

Hình 12.1: Sơ đồ của khối VGA Controller
Tên



t



CLK

Xung clock 27Mhz t
ừ kit DE2.

RESET

Tín hi
ệu reset do khối Timer tr
ì hoãn ban
đ
ầu cung cấp.

oRequest
Tín hi
ệu điều khiển cho phép xuất dữ liệu từ SDRAM
BUFFER và lưu các giá trị của Line Pixel vào khối Line
Buffer.
oVGA_BLANK
oVGA_SYNC
oVGA_VS
oVGA_HS
Các chân này đư
ợc gắn t
ương
ứng v
ào chip gi
ải m
ã

ADV7123 và cổng VGA trên kit DE2 để đồng bộ việc
xuất ra monitor các frames ảnh. Do xuất ảnh theo chuẩn
VGA 640 x 480 nên chân VGA_SYNC luôn phải đặt ở
mức cao để đảm bảo việc đồng bộ.
VGA_X[0]
Cho
bi
ết vị trí của Pixel l
à ch
ẵn hay lẻ để điều khiển việc
tách các thành phần Y, Cr, Cb trong khối xử lý ảnh YUV
VGA_Y[0]
Cho bi
ết Line sẽ hiện thị tr
ên màn hình là thu
ộc Odd
Frame hay Even Frame để chọn dữ liệu đưa ra từ
SDRAM BUFFER

Các chân dữ liệu iRed, iGreen, iBlue được nối trực tiếp với ngõ ra VGA_R,
VGA_G, VGA_B. Ngõ ra oVGA_CLOCK là nghịch đảo của ngõ vào CLK .
4.2 LƯU ĐỒ GIẢI THUẬT
Giải thuật tạo tín hiệu đồng bộ để giao tiếp với VGA là tạo các bộ đếm với
các thông số chuẩn để tạo ra các tín hiệu đồng bộ theo giản đồ thời gian:



Hình 12.2: Vùng hiển thị trong một chu kỳ quét với tình hiệu reset từ hệ thống
Từ các thông số định thì cho chuẩn VGA 640 x 480 60Hz ở trên, do xung
clock trong thiết kế có tần số 27Mhz nên ta chọn các giá trị tương ứng cho các

thông số như sau:
a) Đối với VGA_HS (tín hiệu đồng bộ quy định thời gian hiển thị 1 hàng
trong 1 chu kỳ quét ngang):
H_FRONT = 16, H_SYNC = 96, H_BACK = 48, H_ACT = 640
Như vậy khi hiển thị xong 1 hàng thì phải chờ 1 khoảng thời gian là
H_BLANK = H_FRONT + H_SYNC + H_BACK = 160
(đơn vị là số chu kỳ xung clock) thì hiển thị hàng mới. Lúc này thời gian quét
ngang là: H_TOTAL = H_BLANK + H_ACT = 800.
b) Đối với VGA_VS(tín hiệu đồng bộ quy định thời gian hiển thị 1
frame trong 1 chu kỳ quét toàn bộ màn hình):
V_FRONT = 11; V_SYNC = 2; V_BACK = 31; V_ACT = 480
Như vậy khi hiển thị xong 1 frame thì phải chờ 1 khoảng thời gian là:
V_BLANK = V_FRONT + V_SYNC + V_BACK = 44
(đơn vị là chu kỳ xung quét ngang VGA_HS) thì hiển thị frame mới. Thời gian
quét màn hình là:
V_TOTAL = V_BLANK + V_ACT= 524.
Lưu đồ giải thuật tạo VGA_VS cũng được thực hiện tương tự chỉ khác là
V_Cont được đếm lên sau mỗi cạnh lên của VGA_HS.
4.3 MÔ TẢ
Khối sẽ tạo các tín hiệu điều khiển cho ADV7123 và đồng bộ việc truy xuất,
xử lý dữ liệu với các khối khác dựa trên các tín hiệu định thì quét ngang và quét
dọc như sao:
Tạo tín hiệu quét ngang VGA_HS với bộ đếm lên H_Cont :
always@(posedge iCLK or negedge iRST_N)
begin
if(!iRST_N)
begin
H_Cont <= 0;
oVGA_HS <= 1;
end

else
begin
if( H_Cont < H_TOTAL )
H_Cont <= H_Cont+1'b1;
else
H_Cont <= 0;
//đưa VGA_HS về 0 tương ứng với khoảng thời gian Horizontal SYNC
if(H_Cont == H_FRONT-1)
oVGA_HS <= 1'b0;
if(H_Cont == H_FRONT+H_SYNC-1)
oVGA_HS <= 1'b1;
end
end
Tạo tín hiệu quét dọc VGA_VS với bộ đếm V_Cont theo cạnh lên của
VGA_HS:
always@(posedge oVGA_HS or negedge iRST_N)
begin
if(!iRST_N)
begin
V_Cont <= 0;
oVGA_VS <= 1;
end
else
begin
if(V_Cont < V_TOTAL)
V_Cont <= V_Cont+1'b1;
Else
V_Cont <= 0;
//đưa VGA_HS về 0 tương ứng với khoảng thời gian Hrizontal SYNC
if(V_Cont == V_FRONT-1)

oVGA_VS <= 1'b0;
if(V_Cont == V_FRONT+V_SYNC-1)
oVGA_VS <= 1'b1;
end
end
Sau đó xuất các tính hiệu điều khiển khác:
//tích cực tín hiệu BLANK để xóa các Flicker:
assign oVGA_BLANK = ~((H_Cont < H_BLANK) || (V_Cont
<_BLANK));
//oRquest lên 1 ở thời gian hiển thị frame trong một chu kỳ quét màn hình:
assign oRequest = ( ( H_Cont >= H_BLANK && H_Cont < H_TOTAL )
&& ( V_Cont>=V_BLANK && V_Cont<V_TOTAL ) );
//tính toán vị trí X,Y của Pixel trong frame (X : vị trí pixel trong hàng và Y :
//vị trí hàng trong frame) :
assign oCurrent_X = (H_Cont>=H_BLANK)? H_Cont-H_BLANK : 11'h0;
assign oCurrent_X = (V_Cont>=V_BLANK)? V_Cont-V_BLANK : 11'h0;
Như vậy kể từ khi bắt đầu quét 1 frame thì phải chờ 1 khoảng thời gian có
độ dài là (V_BLANK × H_TOTAL) + H_ BLANK = 35360 (chu kỳ) thì oRequest
mới được tích cực.
5. KẾT LUẬN
6. TÀI LIỆU THAM KHẢO
[1]. Stuart Sutherland, Simon Davidmann, Peter Flake, System
Verilog for Design.
[2]. DAVID R. SMITH, PAUL D. FRANZON, verilog styles for
Synthesis of Digital Systems.
[3]. D. Vanden Bout, VGA Generator for the XSA Boards, XESS
Corporation, October 12, 2004.
[4]. J. BHASKER, A Verilog HDL Primer.
[5]. T. R. PADMANABHAN, B. BALA TRIPURA SUNDARI, Design
Through Verilog HDL.

[6]. FPGA Design with Verilog.
[7]. Peter J. Ashenden, Digital Design.


×