Bộ đệm VGA VGA. Làm thế nào để đọc và viết?


8

Tôi có một bảng Altera DE2 và cố gắng vẽ các họa tiết. Tôi gặp một số khó khăn khi thực hiện bộ đệm màn hình.

Tôi có một thực thể hiển thị rằng ở tốc độ 25 MHZ xuất ra pixel cho màn hình vga.

Tôi đã hy vọng thực hiện một bộ đệm trong SDRAM. Ý tưởng ban đầu là tải pixel pixel tiếp theo với tốc độ 25 MHZ từ SDRAM. Điều này hoạt động, nhưng tôi không thể ghi pixel vào SDRAM ở tốc độ này và cũng không thể xóa màn hình đủ nhanh cho mỗi khung hình mới. Tôi phải mất 2 đồng hồ để ghi dữ liệu và bảng của tôi hoạt động ở mức 50 MHZ vì vậy tôi có đủ thời gian để đọc xong.

Tôi sẽ cho rằng tôi đang làm một cái gì đó khủng khiếp, sai lầm khủng khiếp. Làm thế nào là một bản vẽ như vậy thường được thực hiện trong VHDL?

Điều gần nhất tôi có thể tìm thấy là sử dụng bảng màu 2-3-3 (RGB) để lấy từng pixel và ghi vào ram vải trong thời gian VGA "hiên" (xóa). Điều này có nghĩa là ở mỗi đồng hồ 25 MHz, tôi chỉ có thể cập nhật 15% màn hình và bằng cách nào đó tôi cần mạch của mình để biết được 15% đang cập nhật?

Tôi không thể tìm ra cách sử dụng bộ đệm đôi vì tôi không thể tìm ra cách ghi dữ liệu vào bộ nhớ trong khi đọc. Có cách nào để tránh bit-banging giao thức không? Làm thế nào mà anh chàng này làm điều đó?

nhập mô tả hình ảnh ở đây



@davidcary, với một số chi tiết về cách tiếp cận thực hiện đệm đôi bạn đã trả lời câu hỏi. Tôi nhận ra rằng cần có thời gian và tôi không thể ném đá như một câu hỏi thường đưa ra một câu châm ngôn nhanh để giúp người dùng giải quyết vấn đề của họ cho đến khi ai đó có thể viết câu trả lời chất lượng cao.
Kortuk

3
Khi bạn nói "Có cách nào để tránh đập vào giao thức không?", Tôi cho rằng điều đó có nghĩa là bạn chưa tự mình viết bộ điều khiển SDRAM. Tôi khuyên bạn nên làm như vậy, đó là một bài tập tốt và bạn sẽ hiểu thêm về cách SDRAM hoạt động và cách khai thác thời gian của nó.
mng

Câu trả lời:


3

Một vài cách tiếp cận có thể hữu ích cho một số kiểu hiển thị là chia bảng hiển thị thành các ô và

  1. hạn chế mỗi ô sử dụng một nhóm màu nhỏ, cho phép sử dụng ít hơn 8 bit cho mỗi pixel hoặc
  2. sử dụng một hoặc hai byte từ mỗi ô để chọn vị trí đọc dữ liệu bitmap.
Cách tiếp cận đầu tiên có thể làm giảm tốc độ dữ liệu phải được đọc từ bộ nhớ hiển thị. Ví dụ: nếu một ô được sử dụng có kích thước 16x16 và mỗi ô có thể có bốn màu được chọn từ một bộ 256, thì không sử dụng bất kỳ RAM bổ sung nào trong FPGA, người ta có thể giảm số lần đọc bộ nhớ trên 16 pixel xuống còn tám (bốn giá trị màu, cộng với bốn byte cho bitmap). Nếu thêm một bộ đệm / RAM (*) trị giá 160 byte cho FPGA, người ta có thể giảm số lần đọc bộ nhớ trên 16 pixel xuống còn bốn, sử dụng thêm 160 lần đọc mỗi 16 dòng quét để đọc bộ màu gạch tiếp theo. Nếu một người muốn có 16 màu cho mỗi ô, cách tiếp cận thứ hai sẽ cần thêm 640 byte RAM trừ khi người ta đặt một số hạn chế về số lượng bảng màu khác nhau có thể tồn tại trên một dòng.

Cách tiếp cận thứ hai có thể sẽ tăng thay vì giảm tổng băng thông bộ nhớ cần thiết để tạo màn hình, nhưng sẽ giảm lượng bộ nhớ phải cập nhật để thay đổi màn hình - người ta có thể thay đổi một hoặc hai byte để cập nhật 8 x 8 hoặc Diện tích 16x16 của màn hình. Tùy thuộc vào những gì bạn đang cố gắng hiển thị, có thể hữu ích khi sử dụng kiểu tiếp cận này để sử dụng một thiết bị bộ nhớ để giữ các hình dạng ô vuông và một hình thức khác để giữ lựa chọn ô. Chẳng hạn, người ta có thể sử dụng RAM 32Kx8 nhanh để giữ một vài bản đồ ô 80x60 với hai byte cho mỗi ô. Nếu FPGA không có bất kỳ bộ đệm nào, nó sẽ phải đọc một byte mỗi bốn pixel; ngay cả với RAM tĩnh 40ns, CPU sẽ mất rất nhiều thời gian để cập nhật màn hình (toàn bộ màn hình sẽ chỉ là 9600 byte).

Ngẫu nhiên, nếu người ta không muốn thêm RAM 32Kx8 nhưng có thể thêm 320 byte bộ đệm / RAM (**) vào FPGA, người ta có thể sử dụng cách tiếp cận bản đồ ô vuông nhưng có CPU hoặc DMA cung cấp 160 byte cho hiển thị mỗi 8 dòng quét. Điều đó sẽ gây gánh nặng cho bộ điều khiển ngay cả khi không có gì trên màn hình thay đổi, nhưng có thể đơn giản hóa mạch điện.

(*) Bộ đệm có thể được triển khai dưới dạng RAM hoặc theo chuỗi 32 thanh ghi dịch chuyển dài 40 bit cộng với một chút logic điều khiển.

(**) Bộ đệm có thể được triển khai dưới dạng hai RAM 160 byte hoặc hai nhóm mười sáu thanh ghi dịch chuyển 80 bit.


5

Sprites thường không được thực hiện với bộ đệm khung (theo tôi hiểu từ này). Thay vào đó, bạn so sánh tọa độ x và y với xmin, ymin và xmax, ymax của sprite. Nếu vị trí quét hiện tại nằm trong sprite, hãy xuất màu liên quan từ bộ nhớ sprite.

Nếu bạn đang cố gắng hiển thị bộ đệm khung, hãy lấy trái tim. Đây là dự án lớn đầu tiên của tôi. SDRAM không nên là một vấn đề ở 100 MHz (lần đầu tiên tôi đã làm điều này khoảng một thập kỷ trước và silicon bây giờ sẽ nhanh hơn), vì vậy hãy nhân lên đồng hồ 50 MHz của bạn. Viết bộ điều khiển của riêng bạn sẽ mang tính giáo dục :)

Điều đó cung cấp cho bạn nhiều băng thông để chơi, sau đó bạn có thể tăng gấp đôi bộ đệm, không có vấn đề gì. VGA 60Hz cần trung bình 18Mpixels / giây. Nếu bạn có một thiết bị rộng 16 bit, bạn có băng thông tối đa 200 MB / giây. Ngay cả khi bạn chỉ quản lý để đạt hiệu quả 50% (có thể thực hiện được), đó là 100Mpixels / giây @ 16 bit mỗi pixel hoặc 50Mpixels / giây @ 32 bit mỗi pixel.

Ví dụ: có thể RAM của bạn cần 60ns để thiết lập đọc, nhưng có thể ngắt 8 từ trong 80 ns sau đó - đó là 8 byte trong ~ 140ns. NẾU bạn có thể khiến RAM của mình thực hiện các đợt dài hơn, điều đó sẽ giúp khấu hao chi phí thiết lập đọc.

Dựa trên nhận xét của bạn rằng đó là RAM phía byte, tức là hơn 50 MB / giây, chỉ 16Mpixels / giây @ 24 bit mỗi pixel :( Bạn chỉ không có đủ băng thông để thực hiện màn hình truecolour, ngay cả ở VGA. Tôi có thể thực hiện 8 bit cho mỗi pixel khá dễ dàng, nhưng đó chỉ là 2 hoặc 3 bit cho mỗi màu - điều đó có thể ổn cho ứng dụng của bạn, tôi không biết. Hoặc bạn có thể thực hiện bảng tra cứu 256 màu như ngày xưa - sau sau đó đọc từ bộ đệm khung, sau đó bạn sử dụng giá trị để tra cứu trong đồng hồ RAM bên trong để có được 24 bit (hoặc 18 bit, sẽ phù hợp với màu sắc BRAM) để xuất ra màn hình.

Bộ đệm đôi vẫn hoạt động:

Hiển thị khung hình từ địa chỉ 0 (chỉ cần đọc lần lượt tất cả các pixel, tạm dừng các lần đọc trong khoảng thời gian trống).

Viết khung tiếp theo của bạn vào một vị trí khác. Đối với bộ đệm đôi này, bộ điều khiển DRAM của bạn sẽ phải ưu tiên giữa các nhu cầu cạnh tranh của các kênh đọc và ghi. Gợi ý, ưu tiên các bài đọc vì chúng rất quan trọng :)


Nói chung là tốt hơn để ưu tiên đọc, hay tốt hơn là đọc dữ liệu vào một FIFO, ưu tiên ghi khi một lượng dữ liệu nhất định trong FIFO và ưu tiên đọc khi mức độ FIFO quá thấp? Tôi đã thấy rằng ít nhất là khi điều khiển màn hình LCD có tín hiệu đồng hồ, sẽ rất hữu ích khi cho phép thời gian đọc ở mức khá 'lỏng lẻo' miễn là tất cả dữ liệu được chuyển ra đúng giờ.
supercat

Cảm ơn bài viết của bạn, tôi có thể xem bộ đệm. Nhưng tôi nghĩ phải mất 2 đồng hồ (1/50 MHZ) để đọc dữ liệu và tôi cũng có một thiết bị rộng 8 bit.
Mikhail

@supercat: có, đó là một giải pháp tiên tiến hơn có thể cần thiết nếu băng thông bị đẩy.
Martin Thompson

1
@Misha: Phải mất một thời gian để thiết lập đọc dữ liệu, nhưng bạn có thể đọc số lượng lớn cùng một lúc.
Martin Thompson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.