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

thiết kế hệ thống xử lý ảnh và video trên fpga

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 (830.1 KB, 43 trang )

Chương 4: Sơ lược hệ thống
Trang 33


PHẦN II: THIẾT KẾ HỆ THỐNG

CHƯƠNG 4: SƠ LƯC HỆ THỐNG

4.1. YÊU CẦU
 Tìm hiểu về các giải thuật xử lý ảnh.
 Ứng dụng giải thuật xử lý ảnh video vào phần cứng, cụ thể là mô tả phần cứng
thực hiện giải thuật bằng ngôn ngữ Verilog HDL.
 Ứng dụng FPGAs để kiểm tra kết quả, đồng thời so sánh với kết quả với hình ảnh
video ban đầu.
4.2 NỘI DUNG THỰC HIỆN
 Lấy nguồn tín hiệu video từ DVD ( VCD ) Player đưa vào kit DE2 của Altera qua
cổng TV-IN.
 Sử dụng phần mềm Quartus II của Altera để viết chương trình bằng ngôn ngữ
Verilog HDL và giao tiếp với kit DE2.
 Thiết kế khối lọc trung bình và dò biên cho ảnh ngõ ra bằng Verilog HDL.
 Giao tiếp với ADV7181B, VGA, SDRAM trên kit DE2.
 Hiển thò kết quả lên Monitor và so sánh với tín hiệu gốc

Chương 4: Sơ lược hệ thống
Trang 34

4.3 SƠ ĐỒ THIẾT KẾ VÀ NGUYÊN LÝ HOẠT ĐỘNG
4.3.1 SƠ ĐỒ THIẾT KẾ

Hình 4.1: Sơ đồ hệ thống
4.3.2 NGUYÊN LÝ HOẠT ĐỘNG


 Khối I2C_Video_Config: với giao thức giao tiếp I2C sẽ đặt giá trò cho các thanh
ghi của bộ mã hóa ADV7181 để cấu hình hoạt động cho chip mã hóa này.
 Khối Timer trì hỗn ban đầu: Sau chuỗi khới động, ADV7181B rơi vào thời kì
không ổn đònh, khối sẽ phát hiện thời kì không ổn đònh này rôiø tính toán thời điểm bắt đầu
làm việc của các khối khác.
 Khối Desize_Horizon: Lấy ra chuỗi liên tục các Pixel trong dòng dữ liệu do
ADV7181B xuất ra đồng thời đònh lại kích thước frame ảnh từ dạng 720 x 480 sang chuẩn
VGA 640 x480.
Chương 4: Sơ lược hệ thống
Trang 35

 SDRAM BUFFER: Nhận dữ liệu và tín hiệu điều khiển ghi từ khối Desize Horizon
để ghi giá trò các Pixel vào SDRAM, đồng thời cũùng nhận tín hiệu từ VGA controller để
điều khiển việc xuất dữ liệu, đòa chỉ phù hợp (xuất xen kẽ các line thuộc Odd field và
Even fieldû)
 Khối xử lý ảnh YUV: Xử lý dữ liệu ảnh nhận được từ SDRAM BUFFER rồi xuất ra
dữ liệu ảnh cho khối Convert YUV to RGB
 Khối ConvertYUVtoRGB: ADV7181B xuất ra ảnh video dạng YUV, để có thể
hiển thò lên VGA thì trước tiên chuyển đổi thành dạng RGB.
 Khối VGA_Controller: Nhận dữ liệu ảnh RGB từ khối ConvertYUVtoRGB để xuất
dữ liệu và tín hiệu đồng bộ cho Video DAC 7123, đồng thời cũng phát ra các tín hiệu điều
khiển SDRAM_BUFFER để xuất dữ liệu từ SDRAM.



























Chương 5: Khối I2C_Video_Config
Trang 36


PHẦN III: NỘI DUNG THIẾT KẾ

CHƯƠNG 5: Khối I2C_VIDEO_CONFIG

5.1 SƠ ĐỒ KHỐI

Hình 5.1: Sơ đồ khối I2C_Video_Config



Tên
Mô tả
ICLK
Xung Clock 50MHz từ Kit DE2
RESET
Tín hiệu Reset hệ thống
I2C_SCLK
Ngõ ra chứa xung Clock cung cấp cho ADV7181B
I2C_DATA
Port 2 chiều để cấu hình giá trò các thanh ghi của
ADV7181B




Hình 5.2: Dạng sóng để truyền dữ liệu và cấu trúc ghi với giao thức I2C

Chương 5: Khối I2C_Video_Config
Trang 37

5.2 LƯU ĐỒ GIẢI THUẬT:


5.3 MÔ TẢ
Vai trò của khối chỉ là ghi giá trò vào các thanh ghi của ADV7181B nên có thể chọn
xung clock làm việc của khối là 20KHz nhờ vào bộ chia tần từ tần số 50MHz. Đòa chỉ
Slaver của ADV7181B là 40h nên ta sử dụng cách gán mI2C_DATA <= {8’h40,
LUT_DATA}. Với mI2C_DATA là chuỗi dữ liệu cần truyền trên Bus và LUT_DATA
chứa đòa chỉ của thanh ghi và giá trò cần nạp.

Khi reset, bắt đầu cấu hình lại cho ADV7181B bằng cách xóa giá trò các bộ đếm và
cờ. Sau đó để nạp giá trò cho các thanh ghi ta sử dụng máy trạng thái sau:
Chương 5: Khối I2C_Video_Config
Trang 38

always@(posedge mI2C_CTRL_CLK or negedge iRST_N)
begin
if(!iRST_N) begin
LUT_INDEX <= 0;
mSetup_ST <= 0;
mI2C_GO <= 0; end
else
begin
if(LUT_INDEX < LUT_SIZE)
//LUT_SIZE làsố lần nạp giá trò cho các thanh ghi cần thiết vàLUT_INDEX
//là biến đếm để ánh xạ đến đòa chỉ của các thanh ghi và giá trò cần nạp.
begin
case(mSetup_ST)
0: begin
// Nhập chuỗi dữ liệu cần truyền để đặt giá trò cho các thanh ghi
mI2C_DATA <= {8'h40,LUT_DATA};
mI2C_GO <= 1;
mSetup_ST <= 1;
end
1: begin
if(mI2C_END)
// mI2C_END là cờ báo khi truyền hết chuỗi dữ liệu
Begin
//Có xác nhận ACK là đã nạp xong giá trò cho 1 thanh
ghi từ ADV thì nhảy tới trạng thái 2

if(!mI2C_ACK)
mSetup_ST <= 2;
//Không có xác nhận thì nhảy về trạng thái 0
else
mSetup_ST <= 0;
mI2C_GO <= 0;
end
end
2: begin
Chương 5: Khối I2C_Video_Config
Trang 39

// Tăng LUT_INDEX lên 1 để nhảy đến thanh ghi mới rồi quay về
trạng thái 0
LUT_INDEX <= LUT_INDEX+1;
mSetup_ST <= 0;
end
endcase
end
end
end
Ta chỉ cần đặt giá trò cho một số thanh ghi cần thiết nên không thực hiện việc tăng
dần đòa chỉ thanh ghi mà sẽ ánh xạ từ LUX_INDEX đến LUX_DATA nhờ vào lệnh case,
chẳng hạn như khi LUX_INDEX =27 để nạp giá trò 8’h50 vào thanh ghi có đòa chỉ 8’h00 ta
có cấu trúc:
case(LUX_INDEX):
27: LUT_DATA <= 16'h0050;
Để ADV7181B có thể phát hiện chuẩn video NTSC thì ta sẽ nạp các giá trò cho các
thanh ghi theo bảng giá trò cài đặt ở phần mô tả ADV7181B . Tuy nhiên khi truyền chuỗi
này trên bus ta cần phải thêm các bit đồng bộ: 1 bit cho trạng thái IDE, 2 bit để thiết lập

cờ START, 3 bit để chờ 3 ACK do ADV xác nhận, 3 bit để thiết lập cờ STOP và báo kết
thúc chuỗi, vì vậy thực sự chuỗi dài 33 bit:
case (SD_COUNTER)
6'd0 : begin ACK1=0 ;ACK2=0 ;ACK3=0 ; END=0; SDO=1; SCLK=1;end
//Thiết lập cờ START
6'd1 : begin SD=I2C_DATA;SDO=0;end
6'd2 : SCLK=0;
//Đòa chỉ SLAVER của ADV7181B
6'd3 : SDO=SD[23];
6'd4 : SDO=SD[22];
6'd5 : SDO=SD[21];
6'd6 : SDO=SD[20];
6'd7 : SDO=SD[19];
6'd8 : SDO=SD[18];
Chương 5: Khối I2C_Video_Config
Trang 40

6'd9 : SDO=SD[17];
6'd10 : SDO=SD[16];
//Thả nổi đường truyền để nhập ACK từ ADV7181B qua Port 2 chiều I2C_DATA
6'd11 : SDO=1'bz;
//Đòa chỉ thanh ghi cần nạp
6'd12 : begin SDO=SD[15]; ACK1=I2C_SDAT; end
6'd13 : SDO=SD[14];
6'd14 : SDO=SD[13];
6'd15 : SDO=SD[12];
6'd16 : SDO=SD[11];
6'd17 : SDO=SD[10];
6'd18 : SDO=SD[9];
6'd19 : SDO=SD[8];

// Thả nổi đường truyền nhập để ACK từ ADV7181B qua Port 2 chiều I2C_DATA
6'd20 : SDO=1'bz;
//Giá trò cần ghi vào thanh ghi
6'd21 : begin SDO=SD[7]; ACK2=I2C_SDAT; end
6'd22 : SDO=SD[6];
6'd23 : SDO=SD[5];
6'd24 : SDO=SD[4];
6'd25 : SDO=SD[3];
6'd26 : SDO=SD[2];
6'd27 : SDO=SD[1];
6'd28 : SDO=SD[0];
// Thả nổi đường truyền nhập ACK từ ADV7181B qua Port 2 chiều I2C_DATA
6'd29 : SDO=1'bz;
//Thiết lập cờ STOP và báo kết thúc chuỗi
6'd30 : begin SDO=1'b0; SCLK=1'b0; ACK3=I2C_SDAT; end
6'd31 : SCLK=1'b1;
6'd32 : begin SDO=1'b1; END=1; end
endcase
Trong đó SD_COUNTER thực hiện đếm từ 0 -> 63, như vậy việc nạp cho một thanh
ghi chỉ thực hiện trong 33 chu kỳ đầu còn 30 chu kỳ sau thì Bus ở trạng thái IDE (SCLK =
Chương 5: Khối I2C_Video_Config
Trang 41

1 và SDO = 1) để chờ chu kỳ ghi tiếp theo. Đồng thời để đảm bảo được yêu cầu về dạng
sóng trên chân I2C_SCLK và xác nhận (ACK) đã nạp xong thanh ghi, ta thực hiện:
wire I2C_SCLK = SCLK | ( ( (SD_COUNTER >= 4) & (SD_COUNTER <=30) )?
~CLOCK : 0 );
wire ACK=ACK1 | ACK2 |ACK3;
// khi xét xác nhận đã nạp xong thanh ghi ta sử dụng giá trò bù của ACK(tích cự mức thấp),
chỉ xác nhận khi có đủ 3 xác nhận ACK1, ACK2, ACK3

Và dạng sóng thu được trên chân I2C_SCLK như sau (END từ 0 lên 1 chỉ ra rằng đã
nạp xong giá trò cho một thanh ghi):

Hình 5.3: Dạng sóng mô phỏng trên chân I2C_SCLK














Chương 6: Khối Timer trì hoãn ban đầu
Trang 42

CHƯƠNG 6: KHỐI TIMER TRÌ HOÃN BAN ĐẦU
6.1 SƠ ĐỒ KHỐI

Hình 6.1: Sơ đồ của khối Timer trì hoãn ban đầu

Tên
Mô tả
ICLK
Xung clock 50Mhz từ kit DE2

VS
Tín hiệu VS ( Vertical Sync ) từ ADV7181B
HS
Tín hiệu HS (Horizontal Sync) từ ADV7181B
TD_Stable
Báo hiệu ADV7181b đã hoạt động ổn đònh
RST0, RST1, RST3
Ngõ ra cho phép các khối khác bắt đầu làm việc

6.2 MÔ TẢ
Với cấu hình đã cài đặt ở phần trước, khi đã hoạt động ổn đònh, dạng sóng do
ADV7181B phát ra như sau:

Vì vậy để phát hiện xem chip mã hóa này đã hoạt động ổn đònh hay chưa khối
TD_DETEC tiến hành kiểm tra điều kiện: VS ở mức cao trong 9 chu kỳ liên tiếp của HS
rồi chuyển xuống mức thấp, nếu thỏa mãn thì đưa TD_Stable lên mức cao. Khi tín hiệu
TD_Stable lên mức cao, khối RESET_DELAY bắt đầu đếm lên theo xung nhip của ICLK
Chương 6: Khối Timer trì hoãn ban đầu
Trang 43

(50MHz) để tính thời điểm xuất ra mức 1 trên các chân RST0, RST1, RST2. Các tín hiệu
này dùng để khởi động các khối khác theo trình tự như sau:
1) Ban đầu thì xóa tất cả dữ liệu trong các khối.
2) Tính từ thời điểm TD_Stable lên 1(dơn vò là chu kỳ clock 27MHz) :
 Sau 1132461.5: tích cực RST0 để kích hoạt khối SDRAM BUFFER,
 Sau 1698692.5: tích cực RST1 để kích hoạt khối Desize Horizon
 Sau 2264923.5: tích cực RST2 để kích hoạt khối xử lý ảnh YUV vàVGA Controller.
3) Giữ nguyên giá trò ngõ ra cho đến khi có tín hiệu RESET hệ thống thì lặp lại.
 Điểm cần chú ý ở đây là khi Desize Horizon hoạt động thì sẽ xuất
DATA_VALID cho phép ghi dữ liệu vào SDRAM BUFFER. Rồi phải chờ 1 khoảng thời

gian để ghi đủ số dữ liệu cần thiết mới kích hoạt VGA Controller để xuất dữ liệu từ
SDRAM BUFFER. Như ta đã biết 1 frame ảnh do ADV7181B xuất ra bao gồm 900900
byte (525 line, mỗi line có 1716 byte) hay để truyền hết 1 frame sẽ mất 900900 chu kỳ.
Do xung clock trên chân LLC để truyền các byte là 27 MHz nên ta kiểm tra lại các thời
điểm này như sau:
 Lấy gốc thời gian là khi bắt đầu frame đầu tiên
 TD_Stable lên 1 khi Frame đầu tiên đã phát được 9 line: 9 x 1716 = 15444 chu kỳ.
 Frame thứ 3 được bắt đầu tại thời điểm 2 x 900900 = 1801800
 Khối Desize Horizon được kích hoạt tại thời điểm 1714136.5 (= 15444 + 1698692.5)
tức là trước khi frame thứ 3 bắt đầu. Đảm bảo rằng khối sẽ xuất ra DATA_VALID = 1 ở
toàn bộ các Active Pixel của frame thứ 3.
 Khối VGA controller được kích hoạt tại thời điểm 2280367.5 (=15444 + 2264923.5)
nên oRequest được xuất ra tại thời điểm 2315727.5 (= 2280376.5 + 35360 ). Với 35360
chu kỳ là khoảng thời gian từ khi khối được reset cho đến khi oRequest lên 1. Vậy việc
đọc từ SDRAM BUFFER được kích hoạt khi frame thứ 3 đã bắt đầu được 1 khoảng thời
gian là 513927.5 (= 2315727.5 - 1801800). Điều này đảm bảo cho việc xuất ra đúng từng
frame từ SDRAM BUFFER mà ta sẽ đề cập kỹ hơn ở phần mô tả SDRAM BUFFER.
Cấu trúc và thiết kế của khối này tương đối đơn giản nên ta không đưa lưu đồ giải
thuật và code thực thi mà chỉ mô tả sơ lược.
Chương 7: Khối Desize Horizon
Trang 44

CHƯƠNG 7: KHỐI DESIZE_HORIZON
7.1 SƠ ĐỒ KHỐI

Hình 7.1: Sơ đồ của khối Desize Horizontal

Tên
Mô tả
CLK_27

Xung clock 27Mhz từ kit DE2
RST_N
Reset hệ thống
TD_DATA[7:0]
Dữ liệu hình ảnh từ ADV7181B
ACLR
Tín hiệu xóa bất đồng bộ do khối Timer trì hoãn cung cấp
CLK
Xung clock 27MHz từ chân TD_CLK của ADV7181B
Số chia = 9
Số chia cung cấp cho bộ chia do người thiết kế nhập vào
TV_X[9:0]
Vò trí của Pixel trong hàng hiện hành đồng thời cũng là số
bò chia cung cấp cho bộ chia
Thương [9:0]
Thương của phép chia TV_X cho 9
Số dư [9:0]
Số dư của phép chia TV_X cho 9
DATA_VALID
Đồng bộ cho oYCbCr để đưa vào SDRAM_Controller
oYCbCr[15:0]
Chuỗi dữ liệu ảnh ngõ ra

DATA_VALID: ở mức 1 thì sẽ cho phép Pixel đi kèm được ghi vào SDRAM thông
qua SDRAM_Controller. Do frame mà ADV7181B xuất ra có dạng 720x480 để đưa về
chuẩn 640x480 mà hình ảnh không bò xén thì với mỗi 9 pixel liên tiếp ta sẽ loại bỏ Pixel
Chương 7: Khối Desize Horizon
Trang 45

đầu tiên: không cho phép ghi vào SDRAM bằng cách đưa DATA_VALID xuống mức 0

(lấy ra 8 Pixel trong 9 Pixel :
8
640 720
9

)
Đồng thời để đảm bảo được chuỗi đưa vào SDRAM_controller vẫn có dạng chuỗi
CbYnCrYn+1 liên tiếp thì phải hoán đổi giữa 2 thành phần Cb và Cr cứ sau 2 lần loại bỏ 1
Pixel.

Hình 7.2: Vò trí các Pixel trong chuỗi
Như ở hình trên X là vò trí các Pixel bò loại bỏ (bò bỏ qua khi hiển thò lên màn hình),
khi đó chuỗi Pixel tại S1 là Cb4Y8Cb5 Y10 và tại E1 là Cr8Y17Cr9Y19 vì vậy để đảm bảo
chuỗi ra có dạng CbYCrY liên tiếp thì phải hoán đổi vò trí giữa Cb và Cr trong khoảng Cb5
Y10 Cr8Y17.













Chöông 7: Khoái Desize Horizon
Trang 46


7.2 LÖU ÑOÀ GIAÛI THUAÄT

Chương 7: Khối Desize Horizon
Trang 47

7.3 MÔ TẢ
TD_DATA là chuỗi Pixel được phát ra theo chuẩn Video ITU656. Ta có thể xem
một frame thực sự bắt đầu với Odd Field khi bit F (bit 6 trong Byte cuối của trường SAV
hay EAV) chuyển từ 1 về 0, vậy để xét điều kiện bắt đầu của 1 frame ta phải đợi đến
trường SAV hay EAV rồi mới kiểm tra giá trò của bit F:
Window <= {Window[15:0],iTD_DATA};
if(Window==24'hFF0000)
//khi phát hiện trường SAV (EAV) thì gán giá trò bit V cho FVAL và bit F cho Field
begin
FVAL <= !iTD_DATA[5];
Field <= iTD_DATA[6];
end
//kiểm tra điều kiện bit F chuyển từ 1 về 0 để bắt đầu 1 frame như sau:
Pre_Field <= Field;
if({Pre_Field,Field}==2'b10)
Start <= 1'b1;
//phát hiện trường SAV
Assign SAV = (Window==24'hFF0000)&(iTD_DATA[4]==1'b0);
//khởi động bộ đếm cont để xác đònh số byte của chuỗi Pixel trong 1 hàng
if(SAV)
begin
Cont <= 18'h0;
Active_video <= 1’b0;
end

else if(Cont<1440)
Cont <= Cont+1'b1;
//cứ 2 byte 1 Pixel được nên khi xác đònh vò trí Pixel trong hàng thì phải chia Cont cho 2:
assign oTV_X = Cont>>1;
Để thực hiện phép chia oTV_X cho 9 ta sử dụng bộ chia từ thư viện của Quartus:
Chương 7: Khối Desize Horizon
Trang 48

Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo custom
mới, đặt tên là DIV; chọn phần Arithmetic >> LPM_DEVIDE. Vì oTV_X

720 nên chọn
độ rộng bit của số bò chia (Numerator) là 10, độ rộng bit của số chia (denominator) là 4,
kiểu dữ liệu không dấu. Vì số chia cần nhập là 9 nên ta ghép vào khối tổng thể như sau:
DIV u5 ( .aclr(!DLY0),
.clock(TD_CLK),
.denom(4'h9),
.numer(TV_X),
.quotient(Quotient),
.remain(Remain));
Trong đó quotient, remain là thương và số dư, ta nhập các điều kiện oTV_X có chia
hết cho 9 vàthương là số lẻ thông qua các chân iSkip và iSwap_CbCr bằng cách khai báo:
Desize_Horizontal u4 ( .iTD_DATA(TD_DATA),
.oTV_X(TV_X),
.oYCbCr(YCbCr),
.oDVAL(TV_DVAL),
.iSwap_CbCr(Quotient[0]),
.iSkip(Remain==4'h0),
.iRST_N(DLY1),
.iCLK_27(TD_CLK) );

Sau đó ghép 1 Y với 1 Cr hay 1 Y với 1 Cb đồng thời hoán đổi vò trí của Cr và Cb tại
các vò trí cần thiết:
if(iSwap_CbCr)
begin
case(Cont[1:0]) //hoán đổi Cb Và Cr
0: Cb <= iTD_DATA;
1: YCbCr <= {iTD_DATA,Cr};
2: Cr <= iTD_DATA;
3: YCbCr <= {iTD_DATA,Cb};
endcase
end
else
begin

Chương 7: Khối Desize Horizon
Trang 49

case(Cont[1:0]) // không cần hoán đổi
0: Cb <= iTD_DATA;
1: YCbCr <= {iTD_DATA,Cb};
2: Cr <= iTD_DATA;
3: YCbCr <= {iTD_DATA,Cr};
endcase
end
Sau đó xét thêm điều kiện Cont[0] để đảm bảo việc ghép 1 byte Y với 1 byte Cr hay
1 byte Y với 1 byte Cb đã hoàn thành để xuất DATA_VALID :
if(Start && FVAL && Active_Video && Cont[0] && !iSkip )
Data_Valid <= 1'b1;
else
Data_Valid <= 1'b0;

Như vậy Data_Valid chỉ lên 1 ở Active Pixel để điều khiển sự ghi vào SDRAM BUFFER.













Chương 8: Khối SDRAM BUFFER

Trang 50

CHƯƠNG 8: KHỐI SDRAM BUFFER
8.1 SƠ ĐỒ KHỐI
Gồm 2 khối PLL và SDRAM Controller:

Hình 8.1: Sơ đồ của khối SDRAM BUFFER
Chương 8: Khối SDRAM BUFFER

Trang 51

Tên
Mô tả
RESET

Tín hiệu Reset hệ thống
CLK_27
Xung clock 27Mhz từ kit DE2
CLK
Xung clock 81MHz PLL đưa ra cho các ngõ vào CLK của khối
SDRAM Controller ( chính là tần số đọc của SDRAM WRITE
FIFO, ghi của SDRAM READ FIFO1 và SDRAM READ FIFO2)
SDR_CLK
Xuất xung clock 81MHz cho SDRAM
WR_LOAD
RD1_LOAD
RD2_LOAD
Lần lượt là tín hiệu để xóa bất đồng bộ SDRAM WRITE FIFO,
SDRAM READ FIFO1 và SDRAM READ FIFO2 lấy từ chân
RST0 của khối Timer trì hoãn ban đầu.
WR_DATA
Dữ liệu ảnh đưa vào SDRAM WRITE FIFO do Desize horizon cấp
WR
Cho phép ghi vào SDRAM WRITE FIFO lấy từ chân
DATA_VALID của khối Desize horizon
WR_CLK
Xung clock 27MHz từ chân LLC(TD_CLK) của ADV7181B
RD_WRFIFO
Cho phép đọc dữ liệu từ SDRAM WRITE FIFO
WRITE_SIDE[8:0]
Số từ (Word) hiện có trong SDRAM WRITE FIFO
DATA_IN
Dữ liệu từ SDRAM WRITE FIFO đưa vào Control Center để ghi
SDRAM.
DATA_OUT[15:0]

Dữ liệu Control Center đọc từ SDRAM để xuất ra ngoài qua 1
trong 2 FIFO: SDRAM READ FIFO1, SDRAM READ FIFO2
RD1
RD2
RD1 = ~ RD2: Lần lượt cho phép đọc dữ liệu từ SDRAM READ
FIFO1, SDRAM READ FIFO2 với sự điều khiển của khối VGA
Cotroller thông qua chân Request và VGA_Y.
RD1_CLK
RD2_CLK
Tần số đọc của SDRAM READ FIFO1 và SDRAM READ FIFO2
được là 27MHz từ KIT DE2
READ_SIDE1[8:0]
Số từ (Word) hiện có trong SDRAM READ FIFO1
READ_SIDE2[8:0]
Số từ (Word) hiện có trong SDRAM READ FIFO2
WR_RDFIFO1
Cho phép ghi dữ liệu SDRAM READ FIFO1
WR_RDFIFO2
Cho phép ghi dữ liệu SDRAM READ FIFO2
RD1_DATA[15:0]
RD2_DATA[15:0]
Dữ liệu ngõ ra cung cấp cho khối xử lý ảnh YUV
Các chân DQ[15:0], SA[11:0], CKE, CAS_N, RAS_N, SDR_CLK, WE_N, BA[1:0],
CS_N[1:0], DQM[1:0] thì được nối tương ứng vào chip SDRAM có sẵn trên kit DE2.
Chương 8: Khối SDRAM BUFFER

Trang 52

8.2 LƯU ĐỒ GẢI THUẬT
Lưu đồ dành cho việc ghi và xuất từng khối dữ liệu xen kẽ từ SDRAM.


Chương 8: Khối SDRAM BUFFER

Trang 53

Lưu đồ để xuất hoặc ghi dòng dữ liệu vào các FIFO: ứng với từng thao tác đọc hay
ghi ở trên mà ta có lưu đồ giải thuật tạo đòa chỉ truy cập SDRAM như sau:


8.3 MÔ TẢ
Như ta đã biết 1 frame ảnh theo chuẩn ITU656 bao gồm Odd Field và Even Field:
khi xuất ra màn hình thì các line thuộc Odd Field sẽ được hiển thò ở hàng lẻ, còn các line
thuộc Even là hàng chẵn. Nên các line của 2 Field này phải được xuất xen kẽ nhau nhưng
trong chuỗi video ITU656 do ADV7181B xuất ra thì 2 Field được xuất liên tục: xuất xong
Odd Field rồi mới tới Even Field (các frame khi ghi vào SDRAM thì thành 2 Field liên
Chương 8: Khối SDRAM BUFFER

Trang 54

tục) nên để xuất ra các line xen kẽ thì ta phải tuần tự xuất 1 line từ đòa chỉ mà Odd Field
được lưu giữ rồi lại xuất tiếp 1 line từ đòa chỉ mà Even Field được lưu giữ.
Dữ liệu trong một frame ảnh sẽ được ghi lần lượt vào SDRAM từ đòa chỉ 0 đến đòa
chỉ 324480 (324480 = 640 x 507, 507 chính là số line của frame được ghi vào SDRAM ,ta
bỏ qua 18 line có bit V =1 ), lúc này phần dữ liệu cần xuất ra từ SDRAM chia thành 2
phần (trong 1 frame theo chuẩn ITU656 thực sự có tới 487 active line, ta xén bớt 7 active
line để giảm số line về chuẩn hiển thò là 480):
 Phần 1: Từ đòa chỉ 8320 (640 x 13) đến 161920 (640 x 253) sẽ là các Pixel thuộc
Odd Field. Đây chính là 240 line từ 23 đến 262 trong frame gốc.
 Phần 2: Từ đòa chỉ 170880 (640 x 267) đến 324480 (640 x 507) là các Pixel thuộc
Even Fiel. Đây chính là 240 line từ 286 đến 525 trong frame gốc.

SDRAM hỗ trợ chế độ truy cập dữ liệu theo từng khối (Burst) với chiều dài khối có
thể thay đổi được nhờ vào cài đặt giá trò 3 bit cuối (BL) của thanh ghi mode register bằng
cách truy cập chế độ load mode rồi nhập giá trò cho thanh ghi này qua các chân đòa chỉ:

đây ta đọc và ghi theo từng khối 128 Word 16 bit nên nhập BL = 111: chiều dài
của Burst là full page (tức là 256 word với việc sử dụng SDRAM dưới dạng 4Mx16) ; WT
= 0: truy xuất tuần tự (Sequential) dữ liệu trong khối; LTMODE = 011: thời gian chờ
(latency) cho tín hiệu RAS là 3 chu kỳ;
Các Burst dữ liệu của 2 phần trên sẽ được xuất xen kẽ nhau. Ta khởi tạo và truy
xuất đòa chỉ cho của các phần này như sau:
if(!RESET_N)
begin
rWR_ADDR <= 0;
rWR_MAX_ADDR <= 640*507;
rRD1_ADDR <= 640*13;
rRD1_MAX_ADDR <= 640*253;
rRD2_ADDR <= 640*267;
rRD2_MAX_ADDR <= 640*507;
Chương 8: Khối SDRAM BUFFER

Trang 55

//chiều dài của khối cần truy xuất
rWR_LENGTH <= 128;
rRD1_LENGTH <= 128;
rRD2_LENGTH <= 128;
end
else
begin
//nếu đã thực hiện xong tác vụ mWR_DONE , mRD_DONE và có cờ báo thực hiện tác vụ

mới đối với 1 khối WR_MASK[0], RD_MASK[0], RD_MASK[1] thì tăng đòa chỉ khối lên
1 khối và lăp lại cho đến khi vượt quá đòa chỉ tối đa thì quay về đòa chỉ ban đầu
//ghi vào SDRAM
if(WR_LOAD)
begin
rWR_ADDR <= WR1_ADDR;
rWR_LENGTH <= WR1_LENGTH;
end
else if(mWR_DONE&WR_MASK[0])
begin
if(rWR_ADDR<rWR_MAX_ADDR-rWR_LENGTH)
rWR_ADDR <= rWR_ADDR+rWR_LENGTH;
else
rWR_ADDR <= WR_ADDR;
end
//đọc dữ liệu từ phần 1
if(RD1_LOAD)
begin
rRD1_ADDR <= RD1_ADDR;
rRD1_LENGTH <= RD1_LENGTH;
end
else if(mRD_DONE&RD_MASK[0])
begin
if(rRD1_ADDR<rRD1_MAX_ADDR-rRD1_LENGTH)
rRD1_ADDR <= rRD1_ADDR+rRD1_LENGTH;
else
Chương 8: Khối SDRAM BUFFER

Trang 56


rRD1_ADDR <= RD1_ADDR;
end
//đọc dữ liệu từ phần 2
if(RD2_LOAD)
begin
rRD2_ADDR <= RD2_ADDR;
rRD2_LENGTH <= RD2_LENGTH;
end
else if(mRD_DONE&RD_MASK[1])
begin
if(rRD2_ADDR<rRD2_MAX_ADDR-rRD2_LENGTH)
rRD2_ADDR <= rRD2_ADDR+rRD2_LENGTH;
else
rRD2_ADDR <= RD2_ADDR;
end
end
Trước hết cần tạo một khối điều khiển việc ghi và đọc SDRAM xen kẽ nhau, mỗi
lần đọc hay ghi dữ liệu sẽ thao tác trên từng Burst có chiều dài là 128 từ (Word) theo thứ
tự ưu tiên (chờ thao tác hiện thời hoàn thành rồi mới thực hiện thao tác tiếp theo):
 Đọc 1 khối từ SDRAM rồi ghi vào SDRAM READ FIFO1 để xuất chuỗi Pixel
thuộc Odd Frame
 Đọc 1 khối từ SDRAM rồi ghi vào SDRAM READ FIFO2 để xuất chuỗi Pixel
thuộc Even Frame
 Ghi 1 khối từ SDRAM WRITE FIFO vào SDRAM.
trên ta thực hiện 3 thao tác xen kẽ nhau, vì vậy để dữ liệu có thể đồng bộ nhập,
xuất dữ liệu với các khối khác thì phải cung cấp tần số làm việc cho SDRAM và tần số
truy xuất dữ liệu giữa các khối FIFO và SDRAM gấp 3 lần tần số clock của các khối khác.
Để tạo cac xung clock này ta sử dụng thư viện của Quartus để tạo khối PLL :
Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo một
custom mới, đặt tên là SDRAM_PLL, chọn phần I/O >> ALTCLKlLOCK, ta không sử

dụng các chân đồng bộ mà chỉ nhập các thông số cho tần số ngõ vào và tần số, pha ngõ ra
Chương 8: Khối SDRAM BUFFER

Trang 57

như sau :inclk0 là 27MHz; c0 chọn tần số là 81MHz với pha ban đầu là 0; c1 tần số là 81
MHz với pha ban đầu trễ 3ns (bù trừ với khảng thời gian điều khiển các tín hiệu đồng bộ
để truy cập SDRAM).
Chân c0 sẽ cung cấp tần số đọc tần cho SDRAM WRITE FIFO để ghi dữ liệu vào
SDRAM, tần số ghi cho SDRAM READ FIFO1 và SDRAM READ FIFO2 để ghi dữ liệu
được xuất ra từ SDRAM. Chân c1 cung cấp tần số làm việc cho SDRAM.
Đồng thời khi thực hiện 1 tác vụ ta cần phải trì hoãn các tác vụ khác một khoảng
thời gian được mô tả theo giãn đồ sau (chưa xét tác động của RD1 và RD2):

Hình 8.2: Giản đồ đònh thì cho chu kỳ truy xuất giữa SDRAM và các FIFO
Vì vậy để đảm bảo truy xuất đúng dữ liệu thì cần phải có các FIFO có chiều dài 384
( tức là 128 x 3 ). Tuy nhiên trong thư viện của Quarus chỉ không có FIFO dài 384 Word
nên sẽ tạo một FIFO dài 512 Word như sau:
Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo một
custom mới, đặt tên là SDRAM_WRITE_FIFO, chọn phần Memory Compiler >> FIFO
chọn độ rộng dữ liệu là 16bit, chiều dài ( deep ) là 512 Words. Làm tương tự để tạo các
khối SDRAM_READ_FIFO1 và SDRAM_READ_FIFO2.
Chú ý là: Khi sử dụng FIFO dài 512 Word ta phải có 1 số thay đổi trong thiết kế, tuy
nhiên các thay đổi này tương đối đơn giản như tăng tần số xung clock lên 108 MHz, sử
dụng thêm 1 tác vụ ghi trống (WR2) để đảm bảo dữ liệu xuất ra đung theo yêu cầu.
Thực hiện ghi và xuất từng khối dữ liệu xen kẽ từ SDRAM như sau:

×