FPGA VGA Buffer. Bagaimana cara membaca dan menulis?

8

Saya memiliki papan Altera DE2 dan mencoba menggambar sprite. Saya mengalami masalah dalam menerapkan buffer layar.

Saya memiliki entitas tampilan yang pada tingkat 25 MHZ menghasilkan piksel untuk tampilan vga.

Saya berharap untuk mengimplementasikan buffer di SDRAM. Ide aslinya adalah memuat piksel piksel berikutnya dengan kecepatan 25 MHZ dari SDRAM. Ini berfungsi, tapi saya tidak bisa menulis piksel ke SDRAM pada tingkat ini juga tidak bisa menghapus layar cukup cepat untuk setiap bingkai baru. Saya membutuhkan 2 jam untuk menulis data dan papan saya beroperasi pada 50 MHZ jadi saya punya cukup waktu untuk melakukan pembacaan lengkap.

Saya akan menganggap saya melakukan sesuatu yang sangat, sangat salah. Bagaimana kanvas gambar seperti itu biasanya diimplementasikan dalam VHDL?

Saya paling dekat saya bisa menemukan adalah menggunakan skema warna 2-3-3 (RGB) untuk mengambil setiap piksel dan menulis ke ram kanvas selama "serambi" (blanking) waktu VGA. Ini berarti bahwa pada masing-masing jam 25mhz saya hanya dapat memperbarui 15% dari layar dan entah bagaimana saya membutuhkan rangkaian saya yang mengetahui 15% itu sedang diperbarui?

Saya tidak tahu cara menggunakan buffering ganda karena saya tidak tahu cara menulis data ke memori saat membaca. Apakah ada cara untuk menghindari menggedor protokol? Bagaimana orang ini melakukannya?

masukkan deskripsi gambar di sini

Mikhail
sumber
buffering ganda ?
davidcary
@davidcary, dengan beberapa detail tentang cara melakukan buffering ganda, Anda telah menjawab pertanyaan. Saya menyadari bahwa itu membutuhkan waktu dan saya tidak dapat melempar batu sebagai sesuatu yang sering memberikan sindiran cepat sebagai komentar untuk membantu pengguna dengan masalah mereka sampai seseorang dapat menulis jawaban berkualitas tinggi.
Kortuk
3
Ketika Anda mengatakan "Apakah ada cara untuk menghindari menggedor protokol?", Saya menganggap itu berarti Anda belum menulis sendiri pengontrol SDRAM. Saya sarankan melakukannya, ini adalah latihan yang baik, dan Anda akan lebih memahami tentang bagaimana SDRAM bekerja dan bagaimana memanfaatkan timing-nya.
mng

Jawaban:

3

Beberapa pendekatan yang mungkin berguna untuk beberapa gaya tampilan adalah membagi panel layar menjadi ubin, dan

  1. batasi setiap ubin untuk menggunakan satu set kecil warna, memungkinkan penggunaan kurang dari 8 bit per piksel, atau
  2. gunakan satu atau dua byte dari setiap ubin untuk memilih lokasi untuk membaca data bitmap.
Pendekatan pertama dapat mengurangi tingkat di mana data harus dibaca dari memori tampilan. Misalnya, jika seseorang menggunakan ubin yang berukuran 16x16 dan masing-masing dapat memiliki empat warna yang dipilih dari satu set 256, maka tanpa menggunakan RAM tambahan dalam FPGA, ia dapat mengurangi jumlah memori yang dibaca per 16 piksel menjadi delapan (empat nilai warna, ditambah empat byte untuk bitmap). Jika seseorang menambahkan buffering / RAM (*) 160 byte ke FPGA, orang dapat mengurangi jumlah memori yang dibaca per 16 piksel menjadi empat, menggunakan 160 tambahan membaca setiap 16 garis pemindaian untuk membaca rangkaian warna ubin berikutnya. Jika seseorang menginginkan 16 warna per ubin, pendekatan kedua akan membutuhkan tambahan 640 byte RAM kecuali jika ada pembatasan jumlah palet berbeda yang bisa ada pada satu baris.

Pendekatan kedua mungkin akan meningkatkan daripada mengurangi bandwidth memori total yang diperlukan untuk menghasilkan tampilan, tetapi akan mengurangi jumlah memori yang harus diperbarui untuk mengubah tampilan - seseorang dapat mengubah satu atau dua byte untuk memperbarui 8x8 atau 16x16 area layar. Bergantung pada apa yang Anda coba tampilkan, mungkin berguna saat menggunakan gaya pendekatan ini untuk menggunakan satu perangkat memori untuk menahan bentuk ubin, dan yang lainnya untuk menahan pilihan ubin. Satu mungkin, misalnya, menggunakan 32Kx8 RAM cepat untuk menahan beberapa peta ubin 80x60 dengan dua byte per ubin. Jika FPGA tidak memiliki buffering, ia harus membaca satu byte setiap empat piksel; bahkan dengan 40ns RAM statis, itu akan menyisakan banyak waktu bagi CPU untuk memperbarui tampilan (seluruh layar hanya akan menjadi 9600 byte).

Kebetulan, jika seseorang tidak ingin menambahkan RAM 32Kx8 tetapi bisa menambahkan menambahkan 320 byte buffering / RAM (**) ke FPGA, orang bisa menggunakan pendekatan petak peta tetapi memiliki CPU atau DMA feed 160 byte ke tampilkan setiap 8 garis pindai. Itu akan sedikit membebani controller bahkan ketika tidak ada tampilan berubah, tetapi bisa menyederhanakan sirkuit.

(*) Buffer dapat diimplementasikan sebagai RAM, atau sebagai urutan 32 register shift panjang 40-bit plus sedikit logika kontrol.

(**) Buffer dapat diimplementasikan sebagai dua 160-byte RAM, atau sebagai dua kelompok enam belas 80-bit register geser.

supercat
sumber
5

Sprite biasanya tidak dilakukan dengan frame buffer (seperti yang saya mengerti kata). Sebagai gantinya Anda membandingkan koordinat x dan y dengan xmin, ymin dan xmax, ymax dari sprite. Jika posisi pemindaian saat ini jatuh di dalam sprite, keluarkan warna yang relevan dari memori sprite.

Jika Anda mencoba untuk menampilkan penyangga bingkai, ambil hati. Ini adalah proyek FPGA besar pertama saya. SDRAM seharusnya tidak menjadi masalah pada 100MHz (saya pertama kali melakukannya sekitar satu dekade yang lalu, dan silikon lebih cepat sekarang), jadi gandakan jam 50MHz Anda. Menulis pengontrol Anda sendiri akan mendidik :)

Itu memberi Anda banyak bandwidth untuk bermain, Anda dapat menggandakan buffer, tidak masalah. 60Hz VGA membutuhkan rata-rata 18Mpixels / detik. Jika Anda memiliki perangkat lebar 16-bit, Anda memiliki bandwidth puncak 200MBytes / detik. Bahkan jika Anda hanya berhasil menjadi 50% efisien (yang seharusnya bisa dilakukan) itu 100Mpixels / detik @ 16 bit per piksel atau 50Mpixels / detik @ 32bits per piksel.

Sebagai contoh, mungkin RAM Anda membutuhkan 60ns untuk mengatur pembacaan, tetapi dapat menghasilkan 8 kata dalam 80 ns setelah itu - yaitu 8 byte dalam ~ 140ns. JIKA Anda bisa mendapatkan RAM Anda untuk melakukan burst lebih lama, itu akan membantu mengamortisasi biaya pengaturan membaca.

Berdasarkan komentar Anda bahwa itu adalah byte-side RAM, itu sedikit lebih dari 50MBytes / detik, hanya 16Mpixels / detik @ 24 bit per piksel :( Anda hanya tidak memiliki bandwidth yang cukup untuk melakukan tampilan truecolour, bahkan pada VGA. Anda bisa melakukan 8 bit per piksel dengan mudah, tapi itu hanya 2 atau 3 bit per warna - yang mungkin OK untuk aplikasi Anda, saya tidak tahu. Atau Anda bisa melakukan tabel pencarian 256-warna seperti di masa lalu - setelah membaca dari frame buffer, Anda kemudian menggunakan nilai untuk mencari dalam jam RAM internal untuk mendapatkan 24-bit (atau 18 bit, yang akan cocok dengan BRAM) warna untuk output ke monitor.

Penyangga ganda masih berfungsi:

Tampilkan bingkai dari alamat 0 (baca semua piksel secara bergantian, jeda pembacaan selama interval pengosongan).

Tulis bingkai Anda berikutnya ke lokasi lain. Untuk buffering ganda ini, pengontrol DRAM Anda harus memprioritaskan antara tuntutan bersaing dari saluran baca dan tulis. Petunjuk, prioritaskan bacaan karena mereka kritis terhadap waktu :)

Martin Thompson
sumber
Apakah umumnya lebih baik memprioritaskan pembacaan, atau lebih baik membaca data ke dalam FIFO, memberikan prioritas penulisan ketika sejumlah data ada di FIFO, dan memberikan prioritas pembacaan ketika tingkat FIFO terlalu rendah? Saya telah menemukan bahwa setidaknya ketika mengendarai LCD yang memiliki sinyal jam, ini berguna untuk memungkinkan waktu baca menjadi cukup 'longgar' asalkan semua data akan bergeser tepat waktu.
supercat
Terima kasih untuk posting Anda, saya mungkin melihat buffering. Tapi saya pikir butuh 2 jam (1/50 MHZ) untuk membaca data dan saya juga punya perangkat selebar 8-bit.
Mikhail
@supercat: ya, itu solusi yang lebih maju yang mungkin diperlukan jika bandwidth didorong.
Martin Thompson
1
@Misha: Butuh beberapa saat untuk menyiapkan pembacaan data, tetapi Anda dapat meledak membaca dalam jumlah besar sekaligus.
Martin Thompson