Bagaimana mungkin untuk mengarahkan tampilan VGA pada frekuensi jam piksel tinggi seperti itu?

12

Saya sedang mengerjakan sirkuit digital menggunakan komponen diskrit untuk menggerakkan layar 640x480 VGA dalam mode teks 80x30.

Untuk tampilan 640x480, clock pixel adalah 25.175MHz, yang memiliki periode sekitar 40ns. Saya tidak mengerti bagaimana saya seharusnya bisa menyediakan pixel baru untuk tampilan ini sesering mungkin.

Arsitektur dasar untuk sirkuit saya adalah sebagai berikut:

  1. Penghitung biner untuk piksel horizontal dihitung pada 25.175MHz hingga 800 (640 piksel yang terlihat + 160 untuk teras depan, sinkronisasi, teras belakang). Pada 800, kenaikan penghitung garis vertikal (dan reset pada 525 baris)

  2. Dengan menggunakan posisi horizontal dan vertikal, dapatkan koordinat x, y dari karakter saat ini.

  3. Menggunakan koordinat karakter x, y, indeks ke dalam memori video untuk mengambil karakter ASCII.

  4. Gunakan karakter ASCII untuk mengindeks dalam ROM karakter untuk mendapatkan pola bit untuk karakter

  5. Gunakan register geser paralel ke serial untuk mengonversi 8 piksel garis karakter ke bit individu pada frekuensi jam piksel

Jika Anda mengikuti rantai, ia berbunyi: Counter -> RAM -> ROM -> Parallel to Serial Shift Register

Menggunakan komponen tercepat yang dapat saya temukan, penundaan propagasi dan waktu akses bertambah hingga sekitar 15ns + 20ns + 70ns + 15ns = 120ns, jauh lebih besar dari periode 40ns untuk 25MHz.

Pada resolusi dan kecepatan refresh yang lebih tinggi, Anda dapat memiliki jam piksel di atas 100MHz yang akan menjadi periode 10ns.

Bagaimana mungkin untuk memberikan piksel baru ke layar setiap 10ns ketika waktu akses untuk RAM / ROM sudah jauh di atasnya, bahkan tidak mempertimbangkan semua sinyal lain di sistem Anda?

supershirobon
sumber
7
Anda menggunakan RAM video khusus, dan jam yang langsung masuk ke sinyal video Anda. Anda berupaya mencari tahu apa yang harus ditampilkan jauh sebelum Anda benar-benar menampilkannya.
Hearth
2
Baca tentang Maximite . Itu hanya menggunakan perangkat keras MCU dan beberapa resistor untuk menggerakkan port VGA. Mulailah dengan memeriksa perangkat PIC32 yang dia gunakan. Bekerja dengan baik. (Saya punya Maximite di sini.)
Jonon
"The Video Cookbook Murah" oleh "Don Lancaster"
Jasen

Jawaban:

17

Ada dua alasan utama Anda menemukan tantangan ini.

Pertama, Anda menggunakan bagian yang lebih tua dan lebih diskrit (integrasi skala lebih rendah) daripada yang seharusnya digunakan untuk melakukan ini di era VGA.

Tetapi selanjutnya, Anda menggunakannya dengan cara yang tidak lazim. Secara khusus, pendekatan Anda bukan pipelinedyang berarti bahwa Anda harus menambahkan beberapa penundaan saat menentukan interval Anda, dan dengan demikian menilai.

Sebaliknya, desain digital sinkron yang berupaya mencapai kecepatan mencoba melakukan sesedikit mungkin di antara register.

Walaupun detailnya mungkin akan sedikit berbeda, secara kasar itu akan bekerja seperti ini:

  • Anda menambah atau mengatur ulang alamat, lalu itu masuk dalam register.
  • Anda mengaitkan alamat ke dalam memori sinkron
  • Anda mengunci output dari memori sinkron
  • Anda mengunci ini ke alamat generator karakter sinkron
  • Anda mengunci output dari generator karakter ke register output
  • terapkan pencarian palet ...
  • ke dalam DAC sinkron ...

Ketika Anda memecah tugas seperti ini, Anda hanya mendapatkan satu penundaan kombinatorial ditambah beberapa penundaan propagasi dan mendaftarkan pengaturan dan menahan waktu yang diperlukan agar sesuai antara jam.

Sebuah desain yang dibangun dengan cara ini akan membutuhkan banyak jam untuk menghasilkan output - latensi sebenarnya akan lebih tinggi daripada desain yang murni kombinasi. Tetapi menghasilkan output yang benar baru pada setiap siklus jam yang jauh lebih cepat.

Dan hei, ini video, tidak masalah jika CRT menggambar selusin piksel di belakang penghitung piksel - Anda tentu saja memperhitungkannya dalam waktu sinyal sinkronisasi sehingga mereka benar dibandingkan dengan saat data sebenarnya keluar dari DAC.

Dalam praktiknya, hampir semua sistem digital yang kompleks bekerja dengan cara ini, karena ini adalah ide yang bagus - hingga CPU yang dipipihkan menyentuh ketergantungan pada hasil komputasi sebelumnya atau cabang bersyarat ... Kemudian semuanya menjadi menarik, karena mereka akan berbicara tentang dalam kuliah berikutnya tentang kelas sistem digital - tetapi untungnya situasi VGA Anda jauh lebih sederhana, terutama jika Anda belum khawatir tentang efek sobek jika buffer karakter berubah saat layar sedang diambil.

Sebagai hal praktis jika Anda ingin membangun ini, lakukan dalam FPGA. Itu akan cukup banyak memaksa memori sinkron pada Anda jika Anda menggunakan yang internal, atau register IO sinkron jika Anda menggunakan memori eksternal. Anda akan mendapatkan banyak dorongan ke arah desain yang tepat, kain itu sendiri akan lebih cepat daripada bagian-bagian terpisah Anda, dan tentu saja jika Anda membuat kesalahan, Anda hanya perlu memutar-mutar ibu jari Anda saat mengkompilasi daripada menghabiskan hari yang panjang untuk melakukan pengkabelan kembali. .

Chris Stratton
sumber
"terutama jika Anda belum khawatir tentang efek sobek jika buffer karakter berubah saat layar sedang ditarik" - itulah sebabnya sejak awal krocessor video, krocessor memiliki cara untuk menginformasikan proses utama bahwa mereka tidak saat ini membuang memori mereka ke layar dan jika mereka ingin mengubah buffer video, mereka harus melakukannya sekarang.
John Dvorak
Saya pikir Anda terlalu rumit ini. Dia sudah menyatakan bahwa dia menggunakan register geser 8-bit yang menghasilkan satu bit per jam piksel. Agaknya ini adalah register geser 8-bit dengan kait. Itu berarti dia hanya perlu mengambil byte baru 8 jam pixel, untuk itu tingkat 3,125MHz. Itu memberi Anda semua 320ns untuk mendapatkan data ke kait register geser, yang jauh lebih lama dari 120ns katanya perlu.
Chris_F
Untuk kasus monokrom resolusi rendah yang sangat sederhana, ya, waktu byte tidak akan terlalu menantang, tetapi bagian kunci dari pertanyaan adalah bahwa penanya mencoba memahami bagaimana kinerja sistem "nyata" yang khas dari resolusi non-sepele adalah mungkin. Dan jawabannya sama dengan semua sistem digital lain yang berguna: teknologi lebih cepat dan desain sinkron pipelined.
Chris Stratton
2

Menggunakan komponen tercepat yang dapat saya temukan, penundaan propagasi dan waktu akses bertambah hingga sekitar 15ns + 20ns + 70ns + 15ns = 120ns, jauh lebih besar dari periode 40ns untuk 25MHz.

Anda lupa bahwa adaptor grafis tidak akan pernah hanya menggambar satu piksel - tetapi setidaknya garis pindai penuh. Dengan demikian, ini akan menjadi masalah yang sepenuhnya dapat disalurkan melalui pipa.

Juga, jangan lupa bahwa ada lima dekade perangkat keras penghasil video sejauh ini. Masalah Anda biasanya akan diselesaikan dengan jenis RAM khusus, di mana Anda membuat surat-surat Anda pada satu port, dan yang secara berurutan dibacakan ke sinyal video DAC. Perangkat keras itu jalan, jauh lebih cepat dari apa yang Anda lihat.

Arsitektur dasar untuk sirkuit saya adalah sebagai berikut:

  1. Penghitung biner untuk piksel horizontal dihitung pada 25.175MHz hingga 800 (640 piksel yang terlihat + 160 untuk teras depan, sinkronisasi, teras belakang). Pada 800, kenaikan penghitung garis vertikal (dan reset pada 525 baris)

  2. Dengan menggunakan posisi horizontal dan vertikal, dapatkan koordinat x, y dari karakter saat ini.

Tidak, mengapa kamu melakukan itu? Anda cukup meletakkan piksel baris Anda ke area memori yang berdekatan dan secara linear meletakkannya ke DAC Anda - jika ini adalah tentang implementasi CPU / MCU, Anda bahkan tidak akan membiarkan CPU Anda melakukan itu, tetapi unit DMA, diprogram untuk tidak melakukan apa pun selain mengambil satu nilai setelah yang lain dan menaruhnya ke misalnya port data paralel, tanpa interaksi inti CPU.

  1. Menggunakan koordinat karakter x, y, indeks ke dalam memori video untuk mengambil karakter ASCII.

Ah, Anda ingin membuat dengan cepat - pilihan yang baik, tetapi tidak biasa dengan biaya modern RAM. Alih-alih, Anda hanya akan merender karakter menjadi penyangga bingkai sebelumnya, atau jika perangkat Anda sangat ramping, langsung keluar (lihat penjelasan DMA saya di atas) baris karakter ke DAC.

Marcus Müller
sumber
1
Sementara barang-barang modern cenderung lebih suka framebuffer yang sudah dirender, mereka jelas merupakan pilihan yang buruk jika Anda mencoba bekerja tanpa banyak ram. Jika Anda melakukan ini dalam FPGA, Anda bisa membuat mesin status DMA mengambil alamat dari peta sel karakter dan kemudian membaca dari mesin terbang karakter yang sesuai.
R .. GitHub BERHENTI MEMBANTU ICE
sepenuhnya setuju di sini! karenanya, bagian jawaban saya pada pertanyaan ketiga.
Marcus Müller
2

Terlepas dari pipelining (yang sangat banyak yang harus Anda lakukan), Anda kehilangan sesuatu yang besar ....

Paralel masuk, register geser keluar secara serial memberikan titik pada 25 ganjil Mhz, tentu saja, tetapi jika karakter Anda memiliki lebar 8 piksel, inputnya hanya ~ 3.2MHz yang mudah dijangkau untuk seri LS era VGA, untuk semua itu Anda harus memiliki byte berikutnya yang siap ketika register geser selesai dengan yang sekarang (ini adalah tempat pipa masuk).

Hasilkan jam piksel pada ~ 25MHz dan jam memori pada 1/8 dari itu untuk mendorong buffer teks dan CG ROM, kemudian pipeline memori itu dan hal-hal akses CG ROM.

Satu trik lebih lanjut, output buffer teks akan diulang untuk setiap baris dalam setiap baris teks, jadi mungkin Anda bisa clock 80 byte teks ke buffer cincin dan kemudian berhenti membaca ram untuk 7 baris berikutnya (dengan asumsi 8 karakter garis), ini memungkinkan Anda membebaskan memori untuk digunakan CPU, dengan biaya membutuhkan 80 byte ram yang tergantung di sampingnya.

Dan Mills
sumber
1

Jadi jelas itu tidak berhasil; Anda membutuhkan saluran pipa.

1) Simpan karakter secara bersebelahan dalam memori. Mulai dari kiri atas.

2) Ambil karakter selama interval pengosongan. Lanjutkan untuk mengambil karakter dalam urutan memori.

3) Pipeline setiap karakter yang diterjemahkan dan indeks baris ke dalam ROM.

4) Pipeline output ROM ke buffer.

5) Pipeline buffer ke register geser. Bacakan piksel secara terus-menerus pada interval 40ns dari ini.

(Itu menyiratkan Anda perlu memuat karakter baru ke register geser setiap 320ns, yang bahkan mungkin bisa dilakukan tanpa pipelining seluruh sistem.)

6) Selama pengosongan horizontal, kembali ke awal baris atau maju ke karakter berikutnya (yaitu mulai dari baris berikutnya.)

Fitur bonus: karena Anda hanya memerlukan satu karakter setiap 320ns, Anda juga bisa membaca pasangan karakter + warna dan melakukan karakter warna MSDOS-style atau Spectrum-Style.

pjc50
sumber