Upload
thai-quang-quy
View
106
Download
8
Embed Size (px)
Citation preview
Đồ á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.
Đồ á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
Đồ á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
Đồ á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à
Đồ á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
Đồ á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.
Đồ á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 :
Đồ á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
Đồ á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:
Đồ á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.
Đồ á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
Đồ á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
Đồ á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.
Đồ á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ỳ
Đồ á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.
Đồ á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:
Đồ á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ử
Đồ á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
Đồ á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
Đồ á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Ế
Đồ á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.
Đồ á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:
Đồ á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
Đồ á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];
Đồ á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):
Đồ á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
Đồ á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
Đồ á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
Đồ á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
Đồ á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),
Đồ á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
Đồ á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:
Đồ á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)
Đồ á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.
Đồ á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):
Đồ á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],
Đồ á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
Đồ á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):
Đồ á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;
Đồ á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:
Đồ á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
Đồ á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
Đồ á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.
Đồ á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
Đồ á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
);
Đồ á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 :
Đồ á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};
Đồ á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.
Đồ á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:
Đồ á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);
Đồ á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
Đồ á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:
Đồ á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.
Đồ á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;
Đồ á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.
Đồ á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.