Saya belajar menggunakan FPGA (papan pengembangan Papilio, yang memiliki xilinx spartan3e, menggunakan vhdl).
Saya perlu membagi pulsa yang masuk dengan nomor (hard code).
Saya dapat melihat 3 opsi - kira-kira, sebagai kodesemu (menggunakan 10 hitungan sebagai contoh):
- Inisialisasi ke 0, pada input edge meningkat meningkat sebesar 1, dibandingkan dengan 10; jika keduanya sama, reset ke 0 dan memicu pulsa output
- Inisialisasi ke 10, pada input edge naik berkurang 1, dibandingkan dengan 0; jika keduanya sama, reset ke 10 dan memicu pulsa output
- Inisialisasi ke 9, tetapi pastikan ada setidaknya 1 memimpin "0" bit, yang merupakan bit keluaran saya. Pada sisi input naik, turun 1. Pada sisi naik bit output, reset.
Siklus tugas tidak penting.
Apakah salah satunya lebih baik daripada yang lain? Apakah ada metode yang lebih baik yang belum saya pikirkan?
Apakah ada cara "standar" yang akan memberikan kompiler kesempatan terbaik untuk mengoptimalkan?
Jawaban:
Mengoptimalkan ke level ini akan menghancurkan hati Anda. Hasilnya bisa berubah karena teknologi FPGA yang Anda gunakan, faktor-faktor lain dalam FPGA, tetapi juga karena faktor-faktor di luar kendali Anda, termasuk seed number acak dari pengasuh.
Karena itu, saya percaya bahwa opsi 3 akan menjadi yang terbaik. Opsi 1 dan 2 memiliki gerbang pembanding / ATAU yang berjalan di antara penghitung sehingga dapat memberi sinyal bahwa nomor target telah tercapai. Opsi 2 mungkin sedikit lebih cepat dari 1, karena semuanya bisa lurus ATAU bersama-sama tanpa inverter, tetapi sekali lagi Anda mengalami perbedaan teknologi kecil di mana mungkin lebih cepat untuk DAN atau XOR.
Opsi 3 melewatkan perbandingan untuk biaya rendah satu bit tambahan di penghitung. Ini seharusnya sepadan, kecuali Anda sangat dibatasi dalam sandal jepit.
Satu fakta menyenangkan tentang penghitung adalah bahwa mereka cenderung dikelompokkan ke dalam ukuran spesifik perangkat dalam blok logika, dan Anda akan melihat perubahan waktu lebih dari yang diharapkan jika bit tambahan ini mendorong Anda keluar dari grup itu.
sumber
Satu pilihan lain adalah menginisialisasi penghitung ke 6 (= 2 4 - 10), menghitung, dan mengatur ulang ketika output carry diaktifkan (yaitu, FFs adalah semuanya).
Keuntungan dari hal ini adalah tidak memerlukan FF tambahan, dan banyak FGPA telah mendedikasikan logika bantu untuk mempercepat operasi carry semacam ini di sirkuit penghitung atau penambah.
sumber
Tergantung. Sebagai contoh: penundaan propagasi flip-flop untuk 0 → 1 dan 1 → 0 dapat berbeda, dan karenanya penundaan transisi penghitung untuk 000 → 001 dan 001 → 000 dapat sedikit berbeda. Mungkin lebih tinggi atau lebih rendah, tergantung pada teknologi cmos yang digunakan dalam FPGA. Jadi, Anda harus mensintesis dan mencari tahu mana yang memiliki kinerja waktu yang lebih baik.
sumber
Dari perspektif penulis kompiler: jika Anda menggunakan
integer
, representasi internal tidak ditentukan, dan kompiler bebas untuk memilih implementasi yang paling efisien.Jika Anda memaksakan representasi internal tertentu, pengoptimal masih akan berusaha untuk memperbaikinya, tetapi itu akan mulai dari sudut pandang yang sedikit lebih buruk.
Beberapa FPGA memiliki kemampuan "preload", di mana register dapat diinisialisasi ke nilai arbitrer, dalam hal ini inisialisasi keN- 1 , menghitung mundur dan menggunakan bit carry paling atas sebagai output dan reset (dalam siklus berikutnya) lebih efisien daripada mengimplementasikan baik penambah maupun pembanding. Tanpa preload, penambah mungkin lebih baik.
Kecuali Anda tahu struktur internal, sumber daya dialokasikan ke logika lain (banyak FPGA telah mendedikasikan floating point multiply-tambahkan logika yang juga dapat Anda gunakan untuk mengimplementasikan penghitung jika Anda memiliki unit sisa) dan sepenuhnya yakin bahwa Anda tidak akan beralih untuk model yang berbeda, jawabannya adalah "jangan memikirkannya".
sumber