do an co so gioi thieu ve ngon ngu vhdl va fpga

56
Đồ án cơ sGVHD: Th.s Cao Trn Bo Thương Trang 1 GII THIU ĐỀ TÀI Đề tài này trình bày vthiết kế hthng xnh Video trên FPGA (Cyclone II) bao gm các thành phn: Thu nhn và shóa tín hiu Video Analog, xnh Video s, hin thlên VGA. Trong đề tài này ngoài Cyclone II các thành phn tích hp trên Kit DE2 mà ta ssdng là: Chip mã hóa tín hiu Video Analog ADV7181B, SDRAM IS42S16400 để lưu trvà xut frame nh hp lý, cng VGA (chip ADV7123) để hin thnh lên màn hình.

Upload: thai-quang-quy

Post on 29-Dec-2015

105 views

Category:

Documents


8 download

TRANSCRIPT

Page 1: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 1

GIỚI THIỆU ĐỀ TÀI

Đề tài này trình bày về thiết kế hệ thống xử lý ảnh Video trên FPGA (Cyclone

II) bao gồm các thành phần: Thu nhận và số hóa tín hiệu Video Analog, xử lý ảnh

Video số, hiển thị lên VGA.

Trong đề tài này ngoài Cyclone II các thành phần tích hợp trên Kit DE2 mà ta

sẽ sử dụng là: Chip mã hóa tín hiệu Video Analog ADV7181B, SDRAM IS42S16400

để lưu trữ và xuất frame ảnh hợp lý, cổng VGA (chip ADV7123) để hiển thị ảnh lên

màn hình.

Page 2: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 2

1. GIỚI THIỆU VỀ NGÔN NGỮ VHDL VÀ FPGA

1.1 NGÔN NGỮ VHDL

VHDL là một ngôn ngữ mô tả phần cứng (hardware description language), mô

tả hành vi của mạch điện hoặc hệ thống, từ đó mạch điện vật lý hoặc hệ thống có thể

được thực thi.

VHDL là viết tắt của VHSIC Hardware Description Language. Bản thân

VHSIC là viết tắt của Very High Speed Integrated Circuits (mạch tích hợp tốc độ

cao), lần đầu tiên được sáng lập bởi United State Department of Defense trong những

năm 80, sau đó tạo ra VHDL. Phiên bản đầu tiên là VHDL 87, lần nâng cấp sau đó có

tên là HDL 93. VHDL là ngôn ngữ mô tả phần cứng nguyên gốc đầu tiên được chuẩn

hóa bởi Institue of Electrical and Electronics Engineers (IEEE), tới chuẩn IEEE 1076.

Trong IEEE 1164, có một chuẩn được thêm vào là giới thiệu hệ thống logic đa giá trị

(multi-valued logic system).

Động cơ thúc đẩy cơ bản khi dùng VHDL (hay dùng Verilog) là VHDL là một

ngôn ngữ độc lập chuẩn của các nhà công nghệ, các nhà phân phối do đó chúng có

khả năng portable và kế thừa cao (reusable). Hai ứng dụng trực tiếp chính của VHDL

là trong mảng các thiết bị logic lập trình được (Programmable Logic Devices) (bao

gồm CPLDs – Complex Programmable Logic Devices và FPGAs – Field

Programmable Gate Arrays). Mỗi khi mã nguồn VHDL được viết, chúng có thể được

dùng để thực thi mạch điện trong các thiết bị lập trình được (từ Altera, Xilinx, Almel,

..) hoặc có thể gửi đến các xưởng chế tạo các chíp ASIC. Hiện này, rất nhiều các chip

thương mại phức tạp (ví dụ như các microcontrollers ) được thiết kế dựa trên cách tiếp

cận này.

Một điều chú ý về VHDL là trái ngược với các chương trình máy tính thông

thường được thực hiện tuần tự thì các câu lệnh được thực hiện song song (concurrent).

Vì lí do đó, nên VHDL thường được coi là một mã nguồn hơn là một chương trình.

Trong VHDL chỉ có các câu lệnh đặt trong PROCESS, FUNCTION, hay

PROCEDURE được thực thi tuần tự.

Một trong những tiện ích lớn của VHDL là cho phép tổng hợp mạch điện hoặc

hệ thống trong thiết bị khả lập trình (programmable devide) (PLD hoặc FPGA) hoặc

trong một hệ ASIC.

1.2 FPGA

Page 3: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 3

FPGA (Field Programable Gate Arrays) là một thiết bị bán dẫn bao gồm các

khối logic lập trình được gọi là "Logic Block", và các kết nối khả trình. Các khối

logic có thể được lập trình để thực hiện các chức năng của các khối logic cơ bản như

AND, XOR, hoặc các chức năng kết hợp phức tạp hơn như decoder hoặc các phép

tính toán học. Trong hầu hết các kiến trúc FPGA, các khối logic cũng bao gồm cả các

phần tử nhớ. Đó có thể là các Flip-Flop hoặc những bộ nhớ hoàn chỉnh hơn.

Các kết nối khả trình cho phép các khối logic có thể nối với nhau theo thiết kế

của người xây dựng hệ thống, giống như một bảng mạch khả trình.

Một số kiến trúc FPGA hiện nay còn có thể cho phép cấu hình lại từng phần

(partial re-configuration). Có nghĩa là cho phép một phần của thiết kế được cấu hình

lại trong khi những thiết kế khác vẫn tiếp tục hoạt động.

Một ưu điểm khác của FPGA, là người thiết kế có thể tích hợp vào đó các bộ

xử lý mềm (soft processor) hay vi xử lý tích hợp (embedded processor). Các vi xử lý

này có thể được thiết kế như các khối logic thông thường, mà mã nguồn do các hãng

cung cấp, thực thi các lệnh theo chương trình được nạp riêng biệt, và có các ngoại vi

được thiết kế linh động ( khối giao tiếp UART, vào/ra đa chức năng GPIO, thernet...).

Các vi xử lý này cũng có thể được lập trình lại (re-configurable computing) ngay

trong khi đang chạy.

FPGA được ứng dụng điển hình trong các lĩnh vực như: xử lý tín hiệu số, xử

lý ảnh, thị giác máy, nhận dạng giọng nói, mã hóa, mô phỏng (emulation)...FPGA đặc

biệt mạnh trong các lĩnh vực hoặc ứng dụng mà kiến trúc của nó yêu cầu một lượng

rất lớn xử lý song song, đặc biết là mã hóa và giải mã. FPGA cũng được sử dụng

trong những ứng dụng cần thực thi các thuật toán như FFT, nhân chập (convolution),

thay thế cho vi xử lý.

Hiện nay công nghệ FPGA đang được sản xuất và hỗ trợ phần mềm bởi các

hãng như: Xilinx, Altera, Actel, Atmel... Trong đó Xilinx và Altera là 2 hãng hàng

đầu. Xilinx cung cấp phần mềm miễn phí trên nền Windows, Linux, trong khi Altera

cung cấp những công cụ miễn phí trên nền Windows, Linux và Solaris.

1.2.1 KIẾN TRÚC FPGA

Page 4: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 4

Hình 1.1: kiến trúc FPGA

Mỗi nhà sản xuất FPGA có riêng cấu trúc FPGA, nhưng nhìn chung cấu trúc

được thể hiện giống như trong hình bên trên. Cấu trúc FPGA bao gồm có

configuration logic blocks (CLBs), configurable I/O blocks (IOB), và programmable

interconnect. Và tất nhiên, chúng có mạch clock để truyền tín hiệu clock tới các logic

block, và thêm vào đó có các logic resources như ALUs, memory và có thể có cả

decoders. Các phần tử lập trình được của FPGA có 2 dạng cơ bản là các RAM tĩnh

(Static RAM) và anti - fuses.

Configurable I/O Blocks:

Configurable Logic Blocks (CLBs) bao gồm các Look-Up Tables (LUTs) rất

linh động có chức năng thực thi các logic và các phần tử nhớ dùng như là các flip-flop

hoặc các chốt (latch). CLB thực hiện phần lớn các chức năng logic như là lưu trữ dữ

liệu,..

Configurable I/O Blocks:

Input/Output Blocks (IOBs) điều khiển dòng dữ liệu giữa các chân vào ra I/O

và các logic bên trong của FPGA. Nó bao gồm có các bộ đệm vào và ra với 3 trạng

thái và điều khiển ngõ ra dạng open collector. Phần lớn là có trở kéo lên ở ngõ ra và

Page 5: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 5

thỉnh thoảng lại có trở kéo xuống.IOBs hỗ trợ luồng dữ liệu 2 chiều (bidirectional data

flow) và hoạt động logic 3 trạng thái (3 state). Hỗ trợ phần lớn các chuẩn tín hiệu, bao

gồm một vài chuẩn tốc độ cao, như Double Data-Rate (DDR).

Programmable Interconnect:

Interconnect ở FPGA khác xa so với ở CPLD, tuy nhiên lại giống với của gate array

ASIC. Có một line dài được dùng để nối các CLBs quan trọng mà chúng lại ở cách xa

nhau mà không gây ra quá nhiều trễ. Chúng có thể được dùng như là các bus ở trong

chip. Có các line ngắn được dùng để liên kết các CLBs riêng rẽ nhưng đặt gần nhau.

Và cũng thường có vài ma trận chuyển đổi (switch matrices), giống như trong CPLD,

nối giữa các line dài và ngắn lại với nhau theo một số cách đặc biệt. Các chuyển đổi

lập trình được (Programmable switches) bên trong chip cho phép kết nối giữa CLBs

tới các interconnect line và giữa interconnect line với các line khác và với switch

matrix. Các bộ đệm 3 trạng thái được dùng để kết nối phần lớn các CLBs với các line

dài (long line), tạo nên các bus. Các long line đặc biệt, gọi là các line clock toàn cục

(global clock lines), được thiết kế đặc biệt cho trở kháng thấp và nhờ đó mà thời gian

lan truyền nhanh hơn. Chúng được kết nối với các bộ đệm clock và với mỗi phần tử

được clock trong mỗi CLB. Đó là cách mà clock có thể phân phối bên trong FPGA.

Mạch đồng hồ (Clock Circuitry):

Các khối vào ra với bộ đệm clock high drive gọi là các clock driver, nằm rải

rác xung quanh chip. Các bộ đệm này được nối với các chân clock vào và lái các tín

hiệu clock vào các đường clock toàn cục (global clock line) như mô tả ở bên trên. Các

đường clock được thiết kế sao cho thời gian thời gian lệch nhỏ nhất và thời gian lan

truyền nhanh. Thiết kế đồng bộ là yêu cầu bắt buộc với FPGA, từ khi độ lệch tuyệt

đối và trễ không được bảo đảm. Chỉ khi dùng các tín hiệu clock từ các bộ đệm clock

thì thời gian trễ tương đối và thời gian lệch mới được đảm bảo.

2. CHÍP MÃ HÓA TÍN HIỆU VIDEO ADV7181B

2.1 CHỨC NĂNG VÀ DẠNG DỮ LIỆU NGÕ RA

Nguồn ảnh cần xử lý là tín hiệu analog video do DVD plalyer xuất ra. Kết nối

ngõ ra TV-Out composite của DVD Player với cổng TV-In trên Kit DE2 thì bộ

ADV7181B sẽ số hóa tín hiệu này sang chuẩn ITU - RTBT 656 là chuỗi các frame

ảnh. Mỗi điểm trong frame ảnh thu về được biểu diễn dưới dạng I(x,y) trong đó x,y là

tọa độ của pixel trên frame và I là mức xám tương ứng của pixel đó. Như vậy 1 frame

Page 6: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 6

ảnh thu được sẽ đươc biểu diễn dưới dạng một ma trận 2 chiều 720 x 525 với 720 là

số pixel trên 1 hàng, 525 là số hàng trong 1 frame.

Chuẩn Video ITU – RBT601:

Chuẩn ITU – RBT 610/656 định nghĩa một thiết kế cho việc mã hóa một

khung bao gồm 525 (hoặc 625) line tín hiệu video tương tự thành dạng số, truyền tín

hiệu với xung clock 27MHz. Một single horizontal line có cấu trúc:

EAV BLANKING SAV Active Video Data

EAV, BLANKING và SAV đều là các trường (field) phân biệt để đồng bộ dữ

liệu được truyền.

EAV và SAV đều là các trường 4 byte:

EAV: cho biết điểm kết thúc của Active Video Data trong line hiện hành

cũng như là điểm bắt đầu của line tiếp theo.

SAV: báo hiệu điểm bắt đầu của Active Video Data trong line hiện hành.

FFh 00h 00h XY

Byte thứ tư XY chứa thông tin về trường được truyền, tình trạng của khoảng

trống (field blanking) theo chiều dọc (Vertical) hoặc của dòng trống (line blanking)

theo chiều ngang (horizontal):

MSB LSB

1 F V H P3 P2 P1 P0

Bit Symbol Chức năng

7 1 Luôn ở mức 1

6 F Field Bit: 0 => Field1; 1 => Field2

5 V

Vertical Blanking Status Bit: - Lên mức cao khi ở vertical field blanking interval.

- Xuống mức thấp ở các trường hợp khác.

4 H Horizontal Blanking Status bit: - Nếu là trường SAV thì ở mức 0.

Page 7: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 7

- Nếu là trường EAV thì ở mức 1. 3 P3 Protection bit 3

2 P2 Protection bit 2

1 P1 Protection bit 1

0 P0 Protection bit 0

Các Protecction bit thì dùng để kiểm tra và sửa lỗi phụ thuộc vào các bít

F,V,H. nhưng khi nhận Video Stream ta có thể bỏ qua các bit này nên ta không xét

đến.

Ý nghĩa của các bit F và V là để đảm bảo sự đồng bộ các horizontal line trong

một frame theo chiều dọc:

TABLE 1

Field interval definitions

625 525

V-digital field blanking

Field 1 Start

(V=1)

Finish

(V=0)

Field 2 Start

(V=1)

Finish

(V=0)

Line 624 Line 1

Line 23 Line 20

Line 311 Line 264

Line 336 Line 283

V-digital field identification

Field 1 F=0

Field 2 F=1

Line 1 Line 4

Line 313 Line 266

Cách đặt giá trị các bit F,V theo trường (Field 1 hoặc 2) và tính hiệu dụng

(Active or Blanking) sẽ được hiểu rõ hơn qua bảng mô tả một frame gồm 525

horizontal line sau :

Page 8: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 8

Field 1 (F=0) : 262 line từ line 4 đến line 265; Field 2(F=1) : 263 line từ line

266 đến line 3

Active or Blanking : các Active video data và các Vertical Blanking Interval

được sắp xếp xen kẽ nhau :

Active portion (V=0) Odd Field : 244 line từ 20->263; Even Field: 243 line từ

283->525;

Vertical Blanking Interval (V=1): 38 line gồm 19 line từ 1->19 và 19 line từ

266->282;

Hình 2.1: Frame ảnh theo chuẩn ITU656

Một horizontal line tín hiệu sẽ gồm các thành phần sau:

Blanking: trong suốt thời gian truyền tín hiệu Video, ở giữa các Active video

signal Segments sẽ là các horizontal blanking interval. Giá trị của các byte trong

Page 9: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 9

trường này sẽ phải phù hợp với các cấp độ (level) của các tín hiệu Cb, Cr và Y tương

ứng theo quy tắc sau: Cb = 80h; Y = 10h; Cr = 80h ta có chuỗi byte : 80h, 10h,

80h,…80h,10h.

Tùy vào số line tín hiệu mà chuỗi này sẽ bao gồm 268 byte (khung 525 line)

hoặc là 280 byte (khung 625 line).

Active Video Data: Có tất cả 1440 byte chứa đựng các thông tin về ảnh: 720

giá trị Y (luminace-brightness); 360 giá trị Cr (red chrominace); 360 giá trị Cb (blue

chromiance) được sắp xếp theo từng nhóm cứ một Cb và Cr thì có 2 giá trị Y:

CbYnCrYn+1 tạo thành chuỗi: ………

Các trường SAV và EAV: mỗi trường dài 4 byte

Vậy trong hệ thống 525 line thì một Horizontal line sẽ bao gồm 1716 byte.

2.2 GIAO THỨC CÀI ĐẶT I2C

ADV7181B hỗ trợ một giao diện kết nối 2 dây tuần tự “a-wire serial interface”

I2C. Hai ngõ vào : dữ liệu tuần tự SDA, xung clock tuần tự SCLK mang thông tin

giữa ADV7181B với bộ điều khiển hệ thống I2C. Mỗi thiết bị tới (Slave) sẽ được

nhận ra bởi một địa chỉ duy nhất.

Các chân I2C của ADV7181B cho phép người dùng cài đặt, cấu hình bộ mã

hóa và đọc ngược lại dữ liệu VBI (vertical blank interval) bắt được. ADV7181B có 4

địa chỉ Slave cho tất cả thao tác đọc và ghi phụ thuộc vào mức logic của chân ALSB.

ALSB điều khiển bit 1 của địa chỉ Slave (Slave_address[1] ) bởi việc thay đổi chân

này có thể điều khiển được cả 2 bộ ADV7181B mà không có sự xung đột vì trùng địa

chỉ Slave. Bit thấp nhất của địa chỉ Slave( LSB hay là Slave_address[0] ) quyết định

thao tác ghi hay đọc: mức 1 đọc và mức 0 thì ghi. Ở đây ta chỉ sử dụng 1 bộ

ADV7123, giao thức I2C chủ yếu dùng để nạp dữ liệu cho các thanh ghi nên chọn địa

chỉ Slave cho chip mã hóa này là 0x40h từ bảng giá trị địa chỉ I2C Slave dưới đây:

Page 10: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 10

Để điều khiển thiết bị trên Bus thì phải có một giao thức đặc biệt đi kèm. Đầu

tiên Master sẽ khởi động truyền dữ liệu bằng việc thiết lập điều kiện bắt đầu (SDA

từ 1 xuống 0 trong khi SCLK vẫn ở mức cao) ở đây ta gọi là START, nó ám chỉ rằng

theo sau đó là một luồng địa chỉ hay dữ liệu. Các ngoại vi đáp trả lại START và dịch

chuyển 8 bit tiếp theo (7 bit địa chỉ và 1 bit đọc/ghi), các bit này được truyền từ bit

cao (MSB) đến thấp (LSB). Các ngoại vi khi đã nhận ra các địa chỉ được truyền thì

đáp ứng bằng cách giữ SDA = 0 trong toàn bộ chu kỳ thứ 9 của xung clock gọi là

ACK. Các thiết bị khác thì sẽ rút khỏi bus tại điểm này và bảo toàn trạng thái IDE

(khi cả SDA và SCLK đều ở mức cao để cho các thiệt bị theo dõi 2 line này, chờ

START và địa chỉ được truyền đúng). Bit đọc/ghi chỉ ra hướng của dữ liệu, LSB = 0/1

thì master ghi/đọc thông tin vào/từ ngoại vi.

ADV7181B hoạt động như thiết bị Slave tiêu chuẩn trên Bus, chứa 196 địa chỉ

con (Subaddress là độ lệch của địa chỉ cần thao tác với địa chỉ thiết bị) để cho phép

truy cập các thanh ghi nội. Điều đó giải thích rằng byte đầu tiên là địa chỉ của thiết bị

và byte thứ 2 là địa chỉ con đầu tiên. Các địa chỉ con này tự động tăng dần cho phép

truy đọc/ghi ở địa chỉ con bắt đầu. Sự truyền dữ liệu thì luôn bị ngắt bởi điều kiện

dừng (STOP). Người dùng có thể truy cập tới bất cứ duy nhất 1 thanh ghi ở địa chỉ

con trên cơ sở 1-1 khi không có sự cập nhật toàn bộ các thanh ghi. Ở đề tài này ta

không sử dụng chế độ cập nhật toàn bộ mà chỉ truy cập vào các thanh ghi cần thiết ở

các địa chỉ con trên cơ sở 1-1.

START và STOP có thể xuất hiện ở bất kì đâu trong sự truyền dữ liệu, nếu các

điều kiện này được khẳng định ở ngoài chuỗi liên tục với các thao tác đọc và ghi

thông thường, thì nó tác động làm bus trở về trạng thái IDE. Nếu địa chỉ người dùng

phát ra không phù hợp (invalid) thì ADV7181B sẽ không gửi xác nhận ACK và trở về

trạng thái IDE.

Nếu các địa chỉ con tự động tăng dần rồi vượt quá giới hạn địa chỉ con cao

nhất:

Nếu đang đọc thì những giá trị chứa đựng trong thanh ghi có địa chỉ con cao

nhất sẽ được tiếp tục đọc cho đến khi Master phát 1 NACK (SDK không bị đưa xuống

mức thấp trong toàn bộ chu ky thứ 9) để chỉ rằng việc đọc kết thúc.

Nếu đang ghi thì những giá trị của byte không phù hợp sẽ không được load.

Page 11: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 11

Hình 2.1: Truyền dữ liệu trên bus và chuỗi đọc và ghi tuần tự với giao thức I2C

Truy cập các thanh ghi : MPU có thể viết hoặc đọc các thanh ghi ngoại trừ

các địa chỉ con, chúng chỉ được ghi, chúng chỉ ra các thanh ghi mà tác vụ đọc hay ghi

tiếp theo truy cập đến. Mọi sự giao tiếp với phần này thông qua Bus START với một

sự truy cập các thanh ghi này. Các thao tác ghi hay đọc sẽ được thực hiện từ địa chỉ

đích, rồi tăng lên địa chỉ tiếp theo đến khi một lệnh STOP trên Bus được thực thi.

Lập trình các thanh ghi: cấu hình cho từng thanh ghi, thanh ghi giao tiếp

gồm 8 bit chỉ được ghi. Sau khi thanh ghi này được truy cập trên Bus và một thao tác

đọc/ghi được lựa chọn, các địa chỉ con được cài đặt chỉ ra các thanh ghi mà tác vụ sẽ

đặt tới.

Chọn lựa thanh ghi: (SR đến SR0) những bit này được cài đặt để chỉ ra địa

chỉ bắt đầu được yêu cầu.

Chuỗi I2C : được sử dụng khi cần các thông số vượt quá 8 bit, vì vậy nó

phải được phân phối trên ít nhất 2 thanh ghi của I2C:

Khi một thông số được thay đổi bởi 2 lần ghi thì nó có thể giữ giá trị không

phù hợp (invalid) trong khoảng thời gian lần đầu và lần cuối I2C được hoàn thành, có

nghĩa là các bit đầu của nó có thể mang giá trị mới trong khi các bit còn lại vẫn giữ

giá tri cũ.

Để tránh sai sót này chuỗi I2C sẽ giữ các bit giá trị cập nhật của các thông số

trong bộ nhớ cục bộ, và các bit của chuỗi I2C được cập nhật với nhau một lần khi tác

vụ ghi vào thanh ghi cuối cùng hoàn thành.

Tác vụ hợp lý trên chuỗi I2C sẽ dựa trên cơ sở sau: các thanh ghi dành cho

chuỗi I2C sẽ được ghi theo thứ tự tăng dần địa chỉ các thanh ghi. Ví dụ: HSB[10:0]

thì ghi lên 0x34 trước rồi ngay lập tức ghi thêm vào 0x35.

3. SDRAM IS42S16400

Page 12: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 12

SDRAM IS42S16400 có tất cả 67180864 bit SDRAM được tổ chức thành 4

dải (BANK) nhớ, mỗi dải có dung lượng 1024576 từ (Words) 16 bit với tốc độ truyền

dữ liệu có thể lên đến 133MHz.

3.1 NGUYÊN TẮC HOẠT ĐỘNG

Thực hiện việc truyền dữ liệu qua các chân địa chỉ và dữ liệu dưới sự chi phối

của các chân diều khiển:

CKE cho phép xung clock. Khi tín hiệu này ở mức thấp, chip xử lý giống

như là xung clock hoàn toàn bị dừng lại.

/CS lựa chọn chip: ở mức cao, thì bỏ qua tất cả các đầu vào khác (ngoại

trừ CKE), và hoạt động như một lệnh NOP nhận được.

DQM mặt nạ dữ liệu: Khi cao, những tín hiệu này khống chế dữ liệu

vào/ra. Khi đi kèm với sự viết, dữ liệu không thật sự viết vào. Khi dữ liệu được giữ ở

mức trong hai chu kỳ trước một chu kỳ đọc, việc đọc không được đưa ra từ chip. Trên

một chip nhớ x16 hay DIMM, với 1 từ 8 bit thì có một hàng DQM.

/RAS Row Address Strobe là bit điều khiển cho qua địa chỉ hàng.

/CAS Column Address Strobe bit điều khiển cho qua địa chỉ cột.

/WE Write enable cho phép ghi.

Các tín hiệu /RAS, /CAS, /WE dùng để lựa chọn 1 trong 8 lệnh. Nói chung thì

dùng để phân biệt các lệnh đọc, ghi.

SDRAM bên trong được chia thành trong 2 hay 4 dải (Bank) dữ liệu nội độc

lập bên trong. Một hoặc hai địa chỉ vào của dải (Bank) BA0 và BA1 sẽ lựa chọn Bank

mà lệnh tác động đến.

Phần lớn các lệnh đều sử dụng địa chỉ được đưa vào ngõ vào địa chỉ. Nhưng

có một số lệnh lại không sử dụng chúng, hay chỉ biểu diễn một địa chỉ cột, vì vậy ta

sử dụng A[10] để lựa chọn những phương án.

Bảng 1: Các chế độ truy cập SDRAM

/CS /RAS /CAS /WE Ban A10 An Lệnh

H X X X X X X ức chế các lệnh khác

L H H H X X X Không làm gì cả(NOP)

L H H L X X X

Dừng (hủy) truyền khối: dừng lệnh đọc khối hay ghi khối khi đang thực

Page 13: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 13

hiện.

L H L H Bank L Column Read: đọc khối dữ liệu từ hàng kích hoạt hiện hành.

L H L H Bank H Column

Đọc với Precharge ( nạp lại ) tự động: khi thực hiện xong thì Precharge ( tức là đóng hàng lại).

L H L L Bank L Column Write: ghi khối dữ liệu từ hàng kích hoạt hiện hành.

L H L L Bank H Column

Ghi với sự nạp lại tự động: khi thực hiện xong thì nạp lại (Precharge) tức là đóng hàng lại.

L L H H Bank Row

Active (kích hoạt): mở một hàng với lệnh Read và Write.

L L H L Bank L X

Precharge (nạp lại): Ngưng hoạt động hàng hiện hành của bank (dải) được chọn.

L L H L X H X

Precharge all (nạp lại toàn bộ): Ngưng hoạt động hàng hiện hành của tất cả các bank (dải).

L L L H X X X

Auto refresh (tự động làm tươi): làm tươi từng hàng của từng bank, sử dụng bộ đếm nội. Tất cả các dải phải được nạp lại.

L L L L 0 0 Mode

Lode mode register (chế độ nạp các thanh ghi): A[9:0] được nạp để cấu hình chip DRAM.

Page 14: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 14

Trong đó quan trọng nhất là ngầm định CAS (2 hoặc 3 chu kỳ) và chiều dài khối (1, 2, 4, hoặc 8 chu kỳ).

Sự tương tác các tín hiệu điều khiển SDRAM:

Không có lệnh nào luôn được cho phép:

Lệnh chế độ nạp các thanh ghi (load mode register command) yêu cầu tất cả

các dải (Bank) ở trạng thái IDE, và phải trì hoãn về sau cho sự thay đổi để tác động.

Lệnh tự động làm tươi (auto refresh command) thì yêu cầu tất cả các dải

(Bank) ở trạng thái IDE, và mất 1 khoảng thời gian làm tươi để đưa Chip về trạng thái

IDE: thường là trcd + trp.

Chỉ có những lệnh khác thì cho phép trên một Bank IDE là các lệnh kích hoạt.

Cần phải mất trcd trước khi hàng được mở hoàn toàn và chấp nhận một lệnh đọc hay

ghi.

Khi một dải (Bank) được mở thì có 4 lệnh được cho phép: đọc, ghi, kết thúc

truyền khối (Burst terminal), nạp lại (precharge). Lệnh đọc, ghi bắt đầu truyền khối và

có thể bị ngắt bởi những ngắt sau:

Ngắt một đọc khối dữ liệu:

Sau một lệnh đọc thì bất cứ lúc nào cũng có thể có một trong các lệnh: đọc,

kết thúc truyền khối, hoặc là nạp được phát ra. Và sẽ ngắt đọc khối này nếu có một

ngầm định CAS được cấu hình. Nếu có 1 lệnh đọc ở thời điểm 0, 1 lệnh đọc khác ở

chu kỳ 2, ngầm định CAS ở chu kỳ 3 thì lệnh đọc đầu tiên sẽ truyền khối dữ liệu ra

ngoài ở chu kỳ 3 và 4, và kết quả của lệnh đọc thứ 2 sẽ bắt đầu xuất hiện ở chu kỳ 5.

Nếu lệnh ở chu kỳ 2 là kết thúc truyền khối hoặc là nạp lại Bank kích hoạt thì

không có dữ liệu ra ở chu kỳ 5.

Mặc dù việc ngắt lệnh đọc có thể xuất hiện ở một Bank bất kỳ , nhưng lệnh

nạp lại chỉ ngắt việc đọc khối nếu nó tác động trên cùng một Bank hoặc tất cả các

Bank, nếu lệnh này hướng đến một Bank khác thì việc đọc khối vẫn tiếp tục.

Sự ngắt đọc tạo ra bởi một lệnh ghi thì cũng có thể nhưng sẽ khó khăn hơn.

Thực hiên điều này nhờ vào một tín hiệu DQM để khống chế ngõ ra của SDRAM, vì

vậy trong khoảng thời gian này, chíp điều khiển bộ nhớ có thể lái dữ liệu đi qua chân

DQ để ghi vào SDRAM. Vì tác động của DQM trên lệnh đọc thì bị trì hoãn 2 chu kỳ

Page 15: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 15

trong khi đối với lệnh đọc thì ngay lập tức, nên DQM phải lên mức cao (raised) sớm

hơn 2 chu kỳ trước khi có lệnh ghi.

Để thực hiện điều này trong 2 chu kỳ thì yêu cầu định vị thời điểm SDRAM

tắt ngõ ra tại 1 cạnh lên xung Clock và thời điểm dữ liệu được cung cấp (cho lệnh ghi

) như ngõ vào của SDRAM ở cạnh tiếp theo của Clock.

Một ngắt ghi khối dữ liệu:

Bất kỳ lệnh đọc, ghi, hay kết thúc truyền tới một Bank bất kỳ sẽ kết thúc

(dừng) việc ghi khối ngay lập tức, dữ liệu trên chân DQ khi lệnh thứ 2 được phát thì

chỉ do lệnh này sử dụng.

Ngắt ghi khối với lệnh precharge (đến cung một Bank) thì khá phức tạp. Đó là

thời gian viết nhỏ nhất, twr phải được lướt qua giữa tác vụ ghi sau cùng tới 1 Bank

(chu kỳ không bị che (unmasked) cuối cùng của ghi khối) với lệnh precharge kế tiếp,

vì vậy một ghi khối sẽ bị dừng (hủy) bởi lệnh tích nạp (pre-charge) nếu có đủ chu kỳ

kéo dài được che đi (dùng DQM) để tạo twr cần thiết. Một lệnh ghi với sự tích nạp tự

động chứa đựng một trì hoãn tự động.

Ngắt một lệnh tích nạp tự động:

Việc xử lý sự gián đoạn của thao tác đọc, ghi với chế độ tích nạp tự động là

một đặc tính lựa chọn của SDRAM, và được hỗ trợ rất nhiều. Nếu được sử dụng, sự

tích nạp hay thời gian chờ twr theo sau bởi sự tích nạp (sau khi đọc) bắt đầu cùng một

chu kỳ như một lệnh ngắt.

Sắp xếp truyền khối SDRAM:

Một bộ vi xử lý hiện đại có bộ đệm nói chung sẽ truy nhập bộ nhớ trong

những đơn vị của line bộ đệm. Ví dụ để truyền 64 byte, line bộ đệm yêu cầu 8 sự truy

cập liên tiếp tới một DIMM (dual in-line memory module: module nhớ có hai hàng

chân) 64bit, mà toàn bộ có thể được kích khởi bởi một lệnh đơn đọc hay ghi tùy vào

sự cấu hình các chíp SDRAM.

Sự truy cập line đệm điển hình được kích khởi bởi một sự đọc từ một địa chỉ

đặc biệt, và SDRAM cho phép " từ có tính chất quyết định " của line đệm sẽ được

truyền đầu tiên. ("từ " ở đây có nghĩa là chiều rộng (của) chíp SDRAM hay DIMM,

64 bít với một DIMM tiêu biểu).

Chíp SDRAM hỗ trợ hai giao thức để sắp xếp các từ còn lại trong line đệm:

- Chế độ truyền khối đan xen: làm cho các tính toán của con người thêm

phức tạp nhưng lại dễ dàng tổng hợp phần cứng hơn và được ưu tiên với các bộ vi xử

lý Intel. Ta không sử dụng kiểu truyền này.

Page 16: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 16

- Chế độ truyền khối tuần tự: những từ trễ hơn được truy cập trong việc tăng

dần địa chỉ, khi kết thúc thì quay trở lại điểm bắt đầu khối. Chẳng hạn, với một tuyền

khối có chiều dài là 4, và địa chỉ cột được yêu cầu là 5, những từ sẽ truy cập theo thứ

tự 5-6-7-4. Nếu chiều dài truyền khối là 8, thứ tự truy cập là 5-6-7-0-1-2-3-4. Điều

này được thực hiện bởi việc thêm một bộ đếm địa chỉ cột, và bỏ qua số nhớ khi đi hết

khối.

Ta có thể lựa chọn chiều dài khối và kiểu truy cập khối bằng cách sử dụng chế

độ thanh ghi được mô tả phần tiếp theo.

Chế độ thanh ghi của SDRAM:

Tốc độ dữ liệu đơn SDRAM có một chế độ thanh ghi 10 bít đơn lập trình

được. Sau đó chuẩn SDRAM tốc độ dữ liệu kép SDRAM bổ sung thêm chế độ thanh

ghi, định địa chỉ sử dụng những chân địa chỉ Bank. Với SDR SDRAM, chân địa chỉ

Bank và địa chỉ hàng A[10] và cao hơn thì được lờ đi, nhưng phải là 0 trong khi ở chế

độ ghi vào thanh ghi. Trong chu kỳ của chế độ thanh ghi thì các giá trị nạp vào M[9:0]

chính là các bit địa chỉ.

- M[9] chế độ ghi từng khối, ở mức 0 thì ghi sử dụng chế độ và chiều dài

truyền khối ở chế độ đọc, ở mức 1 thì tất cả các ghi không phải là truyền khối (định vị

đơn).

- M[8:7] chế độ vận hành, muốn ở chế độ lưu trữ thì đặt giá trị 00.

- M[6:4] ngầm định CAS chỉ với các giá trị hợp lệ là 010 (CL2) và 011

(CL3). Chỉ ra số chu kỳ giữa lệnh đọc và dữ liệu được gửi ra từ Chip. Chip sẽ hoàn

thành một giới hạn cơ bản trong nanô-giây dựa trên giá trị này; khi khởi tạo, bộ điều

khiển bộ nhớ phải sử dụng kiến thức của nó về tần số xung Clock và dịch giới hạn kia

thành những chu trình.

- M[3] kiểu truy cập các từ trong khối : 0 thì truy cập tuần tự, 1 thì truy cập

đan xen.

- M[2:0]: chiều dài khối: giá trị 000, 001, 010 và 011 chỉ ra kích thước khối

tương ứng là 1, 2, 4 hay 8 từ. Mỗi đọc ( và viết, nếu m[9] là 0) sẽ thực hiện nhiều sự

truy cập, trừ phi được gián đoạn bởi một sự dừng (hủy) truyền khối hay các lệnh khác.

Giá trị 111 đặc tả khối với đầy đủ hàng (full-row Burst hoặc còn gọi là full page

Burst). Sự truyền khối với đầy đủ hàng chỉ được cho phép với kiểu tuần tự. Đối với

SDRAM IS42S16400 thì chiều dài của 1 khối ở chế độ full page Burst là 256 từ. Sự

truyền khối thì tiếp tục cho đến khi có ngắt.

Làm tươi tự động:

Page 17: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 17

Dùng để làm tươi lại Chip ram nhờ vào sự mở và đóng ( kích hoạt và tích nạp

) từng hàng trong từng Bank. Tuy nhiên, để đơn giản hóa chíp điều khiển bộ nhớ,

Chip SDRAM hỗ trợ lệnh tự động làm tươi, tức là đồng thời thực hiện thao tác này tới

một hàng trong từng Bank. SDRAM cũng duy trì một bộ đếm nội được lặp lại trên

toàn bộ các hàng có thể. Chip điều khiển bộ nhớ thì đơn giản phải phát ra đủ số lượng

các lệnh làm tươi tự động (1 lệnh đối với 1 hàng ) với mỗi khoảng làm tươi (một giá

trị chung là tref = 64 ms). Tất cả các Bank phải ở trạng thái IDE khi lệnh được phát.

Chế độ Lover Power:

Như đã đề cập, ngõ vào cho phép xung Clock (CKE) có thể được dùng để

dừng xung Clock tới SDRAM. Giá trị ngõ vào CKE được xét tại từng cạnh lên của

xung Clock, và nếu ở mức thấp, thì mọi cạnh lên của xung Clock tiếp theo sẽ bị bỏ

qua mọi mục đích khác so với việc kiểm tra CKE.

Nếu CKE xuống thấp trong khi SDRAM đang thực hiện tác vụ, thì nó đơn

giản chỉ là “đóng băng lại” tại chỗ cho đến khi CKE lên mức cao.

Nếu SDRAM ở trạng thái IDE ( tất cả các Bank được tích nạp, không có lệnh

nào đang hoạt động) khi CKE xuống thấp, SDRAM tự động chọn chế độ power-down

(tiết kiệm năng lượng), giữ năng lượng ở cực tiểu cho tới khi có cạnh lên của CKE.

Khoảng này thì không được dài hơn giá trị tối đa khoảng làm tươi tref, nếu không

những gì bộ nhớ chứa đựng sẽ bị mất. Đây là phương pháp để dừng toàn bộ xung

Clock trong khoảng thời gian này để tiết kiệm năng lượng.

Cuối cùng, nếu CKE ở mức thấp vào lúc một lệnh làm tươi tự động được gửi

đến SDRAM, SDRAM chọn chế độ tự làm tươi ( seft-refresh mode). Tương tự Power

Down, nhưng SDRAM dùng một timer nội để phát ra các chu kỳ làm tươi nội khi cần

thiết. Trong thời gian này thì dừng xung Clock. Chế độ tự làm tươi tiêu thụ ít năng

lưọng hơn so với chế độ Power Down, nhưng vẫn cho phép bộ điều khiển bộ nhớ

disable toàn bộ.

4. CƠ CHẾ HIỂN THỊ ẢNH LÊN MONITOR

4.1 NGUYÊN TẮC CHUNG.

Để hiện thị hình ảnh ra màn hình được tích hợp thì cần phải có một bộ VGA

Grenerator với các tín hiệu và cơ chế làm việc như sau:

4.1.1 VGA COLOR SIGNALS.

Có 3 tín hiệu color là: red, green và blue gửi tín hiệu màu sắc (color

information) đến màn hình VGA. Mỗi một tín hiệu điều khiển một súng bắn điện tử

Page 18: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 18

(electron gun) để phóng các hạt electron vẽ lên một màu cơ bản tại một điểm trên màn

hình. Dải của tín hiệu nằm từ từ 0V (tương ứng với màu tối hoàn toàn) và 0.7V (sáng

hoàn toàn) điều khiển cường độ của mỗi thành phần màu và 3 thành phần màu kết

hợp với nhau tạo lên màu của điểm ảnh (dot) hay phần tử ảnh (pixel) trên màn hình.

Hình 4.1: VGA Connection

Tùy vào độ rộng A bít của tín hiệu màu ngõ vào tín mà mỗi màu analog ở ngõ

ra là một trong 2A mức với bộ chuyển đổi digital to analog A bit, 3 tín hiệu analog kết

hợp với nhau tạo nên phần tử ảnh (pixel) với 2A x 2A x 2A = 23A màu khác nhau.

4.1.2 VGA SIGNAL TIMING.

Mỗi một ảnh (hay frame) trên màn hình hiển thị là kết hợp của h dòng, mỗi

dòng có w pixel. Kích thước của mỗi frame được biểu diễn w x h dưới dạng tiêu biểu

gồm 640 x 480m 800 x 600, 1024 x 768 và 1280 x 1024.

Hình 4.2: CRT Display Timing Example

Page 19: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 19

Để vẽ một frame, có những mạch điện có trách nhiệm di chuyển dòng electron

từ trái sang phải và từ trên xuống dưới dọc theo màn hình gọi là deflection circuit.

Những mạch này yêu cầu phải có 2 tín hiệu đồng bộ để khởi động và dừng dòng

electron tại đúng thời điểm để cho một dòng các điểm ảnh được vẽ dọc theo màn hình

và mỗi dòng được điền theo cơ chế từ trên xuống dưới để tạo lên một ảnh.

VGA Display Timing với chế độ 640 x 480:

Symbol Parameter Vertical Sync Horizontal Sync

Time Clocks Lines Time Clocks

Ts Sync pulse time 16.7 ms 416,800 521 32µs 800

TDISP Display time 15.36 ms 384,000 480 25.6µs 640

TPW Pulse width 64µs 1,600 2 3.84µs 96

TFP Front porch 320µs 8,000 10 640ns 16

TBP Back porch 928µs 23,200 29 1.92µs 48

4.1.3 VGA GENERATOR.

Hệ thống bên ngoài ghi giá trị pixel vào trong thanh ghi pixel (data register).

Nội dung của thanh ghi này được dịch sau mỗi xung cloch để thay thế pixel hiện tại.

Các bit này được gửi đến bộ DAC để chuyển sang dạng tín hiệu màu analog. Rồi

kiểm tra xem giá trị trên chân Blank để xuất ra cổng VGA.

Hai mạch tạo xung đồng bộ (pulse generation circuit) được dùng để tạo các

xung đồng bộ dọc (VSYNC) và ngang (HSYNC). Bộ hirizontal sync generator có đầu

ra là tín hiệu gate một chu kì trùng khớp với sường lên của xugn đồng bộ ngang

(horizontal sync pulse), tín hiệu gate này nối với tín hiệu clock – enable của bộ

vertical sync generator vì thế nên clock – enable chỉ cập nhật bộ đến thời gian sau mỗi

dòng pixel (line of pixels). Tín hiệu gate của vertical sync generator được dùng như

tín hiệu báo kết thúc một frame, đồng thời nó cũng reset và xóa toàn bộ nội dung của

pixel buffer nên bộ VGA generator luôn khởi động từ trạng thái xóa sạch hoàn toàn

với mọi frame.

Bộ tạo tín hiệu đồng bộ cũng tạo ra các tín hiệu horizontal và vertical

blanking. Khi dùng phép toán OR logic ta được tín hiệu blanking toàn cục.

4.2 BỘ VGA DAC ADV7123

Kit DE2 tích hợp một bộ VGA DAC và ADV7123 với cấu trúc

Page 20: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 20

Hỗ trợ tín hiệu màu 10 bit ở ngõ vào, với bộ DAC 10 bit sẽ cho ra mức

màu Analog ở ngõ ra, tuy nhiên trong thiết kế dữ liệu màu ta cung cấp cho ADV7181

chỉ là 8 bit nên tín hiều màu ở Analog ngõ ra có mức 3, tín hiệu analog kết hợp lại với

nhau tạo nên phần tử ảnh (16 triệu) màu, 1028224.

Các tín hiệu đồng bộ là SYNC và BLANK: giá trị của SYNC thì không

ảnh hưởng đến quá trình hiển thị, BLANK với giá trị 0 thì chốt các dữ liệu màu ở ngõ

vào.

Hình 4.3: Sơ đồ cấu trúc ADV7123

Các chân của ở ngõ ra được nối tương ứng với các chân của cổng VGA

trên KIT DE2, vì vậy để sử dụng được bộ VGA DAC này ta phải tạo ra một khối vừa

cung cấp các tín hiệu BLANK, Red, Green, Blue cho ADV7123 vừa phải tạo ra 2 tín

hiệu đồng bộ VSYN và HSTNC nối trực tiếp vào cổng VGA một cách đồng thời.

5. SƠ LƯỢC HỆ THỐNG

5.1 SƠ ĐỒ THIẾT KẾ

Page 21: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 21

Hình 5.1: Sơ đồ hệ thống

5.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ì hoãn ban đầu: Sau chuỗi khởi động, ADV7181 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 Disize_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 x 480.

SDRAM BUFFER: Nhận dữ liệu và tính hiệu điều khiển ghi từ khối

Disize_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: ADV718B xuất ra ảnh video dạng YUV, để có thể

hiện thị lênh 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 DAC7123, đồ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.

Page 22: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 22

6. KHỐI I2C_VIDEO_CONFIG

6.1 SƠ ĐỒ KHỐI

Hình 6.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 các giá trị thanh ghi của ADV7181B

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

6.2 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 số 50MHz. Địa chỉ

Slaver của ADV7181B là 40h nên ta sử dụng cách gán mI2C_DATA là kiểu 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:

Page 23: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 23

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

//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 một 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

Page 24: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 24

//tăng LUT_INDEX lên 1 để nhảy đến thay 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 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’50 vào thanh ghi địa

chỉ 8’h00 ta có cấu trúc:

case(LUX_INDEX):

27: LUT_DATA <= 16’h0050;

Để AVD7181B 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ờ ACK cho 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];

6’d9 : SDO=SD[17];

6’d10 : SDO=SD[16];

Page 25: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 25

//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_COUTER thực hiện đếm từ 0 đến 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=1 va SDO=1) để chờ chu kỳ 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_COUTER>=4) &

(SD_COUTER<=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ự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):

Page 26: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 26

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

7. KHỐI TIMER TRÌ HOÃN BAN ĐẦU

7.1 SƠ ĐỒ KHỐI

Hình 7.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

7.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:

Hình 7.2: Mô tả dạng sóng ADV7181B

Page 27: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 27

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 nhịp

của ICLK (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:

a) Ban đầu xóa tất cả dữ liệu trong các khối.

b) Tính từ thời điểm TD_Stable lên 1 (đơ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.

c) 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ờ một

khoảng thời gian để ghi đủ số 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 một 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 một frame sẽ

mất 900900 chu kỳ. Do xung clock trên chân LLC để truyền các byte là 27MHz 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ứ ba đượ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ứ ba 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 một khoảng thời gian là 513927.5(= 2315727.5 – 1801800). Điều này

Page 28: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 28

đả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.

8. KHỐI DISIZE_HORIZON

8.1 SƠ ĐỒ KHỐI

Hình 8.1: Sơ đồ khối Disize_Horizon

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

Page 29: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 29

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 720 x 480

để đưa về chuẩn 640 x 480 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 đầ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: 640 = x 720 ).

Đồ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 8.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à Cb4Y8Cb5Y10 và tại E1 là Cr8Y17Cr9Y19 vì vậy để

đảm bảo chuỗi có dạng CbYCrY liên tiếp thì phải hoán đổi vị trí giữa Cb và Cr trong

khoảng Cb5Y10…Cr8Y17.

8.2 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

Page 30: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 30

trường SAV hay EAV) chuyển từ 1 về 0, vậy để xét điều kiện bắt đầu của một 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;

//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 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

quatus:

Phần Menu >> Tools >> MegaWizard Plug_in Manager…>>Create… tạo

custom mới đặt tên là DVI; chọn phần Arithmetic >> LPM_DEVIDE. Vì oTV_X ≤

720 nên chọn độ rộng bit của số bị chia (Numberator) 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),

Page 31: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 31

.number(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

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

Page 32: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 32

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.

9. KHỐI SDRAM BUFFER

9.1 SƠ ĐỒ KHỐI

Gồm 2 khối PLL và SDRAM Controller:

Page 33: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 33

Hình 9.1: Sơ đồ khối SDRAM BUFFER

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)

Page 34: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 34

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.

Page 35: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 35

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.

9.2 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 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):

Page 36: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 36

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 Field. Đâ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 đọc và ghi theo từng khối 128 word 16 bit nên nhập BL = 111: chiều

dài của Burts là full page (tức là 256 word với việc sử dụng SDRAM dưới dạng 4M

x 16); 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à chi

xuất địa chỉ cho 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;

//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 một khối WR_MASK[0], RD_MASK[0],

Page 37: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 37

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

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

Page 38: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 38

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 các 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 >> ALTCLKILOCK, 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ố ngõ ra 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 số 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):

Page 39: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 39

Hình 9.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ỉ 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.

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:

//ghi vào SDRAM READ FIFO1 các Pixel thuộc line Odd frame

if( (READ_SIDE1< rRD1_LENGTH) )

begin

mADDR <= rRD1_ADDR;

mLENGTH <= rRD1_LENGTH;

WR_MASK <= 2'b00;

RD_MASK <= 2'b01;

mWR <= 0;

mRD <= 1;

end

//ghi vào SDRAM READ FIFO2 các Pixel thuộc line Even frame

else if( (READ_SIDE2< rRD2_LENGTH) )

begin

mADDR <= rRD2_ADDR;

Page 40: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 40

mLENGTH <= rRD2_LENGTH;

WR_MASK <= 2'b00;

RD_MASK <= 2'b10;

mWR <= 0;

mRD <= 1;

end

//đọc dữ liệu từ SDRAM WRITE FIFO và ghi vào SDRAM

else if( (WRITE_SIDE>= rWR_LENGTH)&& (rWR_LENGTH!=0) )

begin

mADDR <= rWR_ADDR;

mLENGTH <= rWR_LENGTH;

WR_MASK <= 2'b01;

RD_MASK <= 2'b00;

mWR <= 1;

mRD <= 0;

end

end

if(mWR_DONE)

begin

WR_MASK <= 0;

mWR <= 0;

end

if(mRD_DONE)

begin

RD_MASK <= 0;

mRD <= 0;

end

Xét điều kiện số Word có trong các FIFO để khởi tạo lệnh đọc và ghi

SDRAM. Rồi dùng biến đếm ST (bắt đầu từ 0) để thiết lập khoảng thời gian cần thiết

cho 1 tác vụ bao gồm: thời gian chờ bus đảm bảo rảnh hoàn (đối với lệnh đọc là

SC_CL+SC_RCD+1, ghi là SC_CL-1, phụ thuộc vào cấu trúc của SDRAM: SC_CL

= SC_RCD = 3 được khai báo trong tập tin Sdram_Params.h ), thời gian thực hiện tác

vụ (mLENGTH = 128).Tạo tín hiệu điều khiển việc ghi đọc các FIFO và cờ báo đã

đọc hay ghi xong như sau:

Page 41: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 41

if(Read)

begin

//OUT_VALID là tín hiệu dùng để điều khiển cho phép ghi vào các SDRAM

//READ FIFO

if(ST==SC_CL+SC_RCD+1)

OUT_VALID <= 1;

else if(ST==SC_CL+SC_RCD+mLENGTH+1)

begin

OUT_VALID <= 0;

Read <= 0;

mRD_DONE <= 1;

end

end

else

mRD_DONE <= 0;

if(Write)

begin

//IN_REQ là tín hiệu dùng để điều khiển cho phép đọc từ SDRAM WRITE

//FIFO

if(ST==SC_CL-1)

IN_REQ <= 1;

else if(ST==SC_CL+mLENGTH-1)

IN_REQ <= 0;

else if(ST==SC_CL+SC_RCD+mLENGTH)

begin

Write <= 0;

mWR_DONE <= 1;

end

end

else

mWR_DONE<= 0;

với chu kỳ truy xuất như giản đồ trên thì lượng dữ liệu xuất ra sẽ gấp 2 lần

lượng dữ liệu ghi vào SDRAM. Tuy nhiên quá trình trên còn chịu ảnh hưởng của các

Page 42: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 42

ngõ vào RD1 và RD2, (tác động đến các giá trị READ_SIDE1 và READ_SIDE2) sẽ

điều khiển các thao tác xuất dữ liệu từ SDRAM vào SDRAM READ FIFO như sau:

- RD1 = ~RD2 = 1: ngừng tác vụ xuất dữ liệu từ SDRAM vào SDRAM

READ FIFO2 tức là chỉ xuất các line của Odd Field.

- RD1 = ~RD2 = 0: ngừng tác vụ xuất dữ liệu từ SDRAM vào SDRAM

READ FIFO1 tức là chỉ xuất các line của Even Field.

Do RD1, RD2 được tích cực lần lượt sau 640 chu kỳ (tương đương với 1 line)

nên các line sẽ được xuất xen kẽ nhau. Như vậy trong 1 chu kỳ truy xuất thực sự chỉ

có 128 Word được xuất vào 1 FIFO, đảm bảo được sự đồng bộ dữ liệu của SDRAM

với hệ thống.

Vấn đề cuối cùng cần phải giải quyết là xác định các thời điểm truy xuất

SDRAM BUFFER tức là tính toán khoảng thời gian kể từ khi bắt đầu ghi dữ liệu

vào(WR=1) và tới khi bắt đầu xuất chúng ra để đảm bảo các pixel được xuất ra là

cùng thuộc 1 frame:

- Nếu khoảng thời gian này không đủ lớn: chân RD2 tích cực bắt đầu truy

xuất dữ liệu của Even Field từ địa chỉ 170880 cho đến 324480, mà dữ liệu trong các

địa chỉ này lại chưa được cập nhật nên dẫn đến các line xuất ra sẽ không có giá trị

hoặc là các line của frame trước.

- Nếu khoảng thời gian này quá lớn: do tốc độ tăng địa chỉ của quá trình ghi

gấp đôi quá trình đọc (do địa chỉ ghi được tăng liên tục còn chỉ đọc lần lượt là địa chỉ

để xuất xen kẽ các line thuộc Odd Field và Even Field nên cũng chỉ được tăng lần

lượt), nên xảy ra trường hợp khi đang xuất dữ liệu thuộc 1 frame thì quá trình ghi đã

nhập dữ liệu của frame tiếp theo vào SDRAM BUFFER, khi đó RD1 tích cực thì có

thể xuất ra 1 line thuộc frame mới này chứ không phải là line của frame hiện hành.

Như đã nói trong phần mô tả khối Timer trì hoãn ban đầu, việc đọc từ

SDRAM BUFFER được kích hoạt sau 1 khoảng thời gian là 513927.5 chu kỳ tính từ

khi frame thứ 3 bắt đầu: khi các Pixel trên line thứ 300 của frame gốc ( 513872.5 ÷

1716; với1716 là số byte của 1 line trong frame gốc) tương đương với line thứ 282

(bỏ qua18 line có bit V =1) đang được ghi vào SDRAM BUFFER, thì bắt đầu xuất

xen kẽ các line. Điều kiện RD2 truy xuất đúng Even frame được thỏa mãn, xét các

line mà RD1 xuất ra:

- Khi WR ghi liên tục từ line 282 đến line 507 vào SDRAM BUFFER thì

hiển nhiên là RD1 truy xuất đúng. Lúc này line mà RD1 đang xuất là 13 + (507 - 282)

÷ 2 = 125.5

Page 43: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 43

- Xét frame tiếp theo: phải chờ hết 9 line đầu tiên mới bắt đầu ghi từ line 0.

Lúc đó RD1 sẽ truy xuất line thứ 125.5 + 9 : 2 = 130; như vậy cho đến khi RD1 xuất

line xong line thứ 253 thì WR mới chỉ ghi tới line (253-130)×2 = 246. Đảm bảo dữ

liêu được xuất vẫn là của frame hiện thời.

Ngoài ra trong khối Control Center còn có các khối command, control

interface để tạo và đồng bộ các lệnh làm tươi (refresh), tích nạp (Precharge), chọn chế

độ đọc, ghi, truyền khối, đồng thời mã hóa và giải mã lệnh cho SDRAM theo mô tả

các chế độ truy cập SDRAM ở Bảng 1.2 với cấu trúc khá phức tạp. Trong khuôn khổ

đồ án này không đề cập đến mà chỉ tham khảo và sử dụng code verilog từ công ty

Altera và hãng sản xuất KIT DE2 là Terasic.

Khi ghép vào trong khối tổng thể ta sẽ dùng cấu trúc để xuất dữ liệu như sau:

.RD1_DATA(m1YCbCr), .RD2_DATA(m2YCbCr), rồi chọn dữ liệu để đưa vào khối

xử lý ảnh YUV : assign mYCbCr_d = !VGA_Y[0]? m1YcbCr : m2YCbCr; với

!VGA_Y[0] là do khối VGA Controller đưa ra cho biết line đang xuất trên màn hình

ở vị trí lẻ hay chẵn để chọn dữ liệu xuất ra tương ứng.

10. KHỐI XỬ LÝ ẢNH YUV

10.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.

Page 44: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 44

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.

10.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

Page 45: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 45

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

);

Page 46: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 46

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 |Gx| và |Gy|: 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 :

Page 47: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 47

Maët naï loïc chæ coù caùc heä soá 0, 1, 2 , -1 vaø -2 ( k =1, 2 ñaõ xeùt ôû pheùp loï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 Gx và Gy 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};

Page 48: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 48

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.

11. KHỐI CONVERT YCRCB TO RGB

11.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.

Page 49: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 49

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.

11.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 2k 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:

Page 50: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 50

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:

596d = 254h , 817d = 331h , -200d = F38h (số bù hai), -416d = E60h (số bù hai), 1033d =

409h .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);

Page 51: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 51

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.

12. KHỐI VGA CONTROLLER

12.1 SƠ ĐỒ KHỐI

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

Page 52: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 52

Tên Mô 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 .

12.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:

Page 53: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 53

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.

Page 54: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 54

12.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;

Page 55: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 55

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.

13. KẾT LUẬN

14. 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.

Page 56: Do an Co So Gioi Thieu Ve Ngon Ngu Vhdl Va Fpga

Đồ án cơ sở GVHD: Th.s Cao Trần Bảo Thương

Trang 56

[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.