Di utas komentar pada jawaban untuk pertanyaan ini: Output yang salah dalam entitas VHDL dinyatakan:
"Dengan bilangan bulat, Anda tidak memiliki kontrol atau akses ke representasi logika internal di FPGA, sementara SLV memungkinkan Anda melakukan trik seperti memanfaatkan rantai pembawa secara efisien"
Jadi, dalam keadaan apa Anda merasa lebih rapi untuk menggunakan vektor representasi bit daripada menggunakan integer untuk mengakses representasi internal? Dan apa kelebihan yang Anda ukur (dalam hal area chip, frekuensi clock, delay, atau sebaliknya.)?
Jawaban:
Saya telah menulis kode yang disarankan oleh dua poster lain di keduanya
vector
dan dalaminteger
bentuk, berhati-hati agar kedua versi beroperasi dengan cara yang sama mungkin.Saya membandingkan hasil dalam simulasi dan kemudian disintesis menggunakan penargetan Synplify Pro Xilinx Spartan 6. Sampel kode di bawah ini ditempel dari kode kerja, jadi Anda harus dapat menggunakannya dengan synthesizer favorit Anda dan lihat apakah perilakunya sama.
Downcounters
Pertama, downcounter, seperti yang disarankan oleh David Kessner:
Arsitektur vektor:
Arsitektur integer
Hasil
Dari segi kode, bilangan bulat sepertinya lebih disukai bagi saya karena menghindari
to_unsigned()
panggilan. Kalau tidak, tidak banyak yang bisa dipilih.Menjalankannya melalui Synplify Pro dengan
top := 16#7fff_fffe#
menghasilkan 66 LUT untukvector
versi dan 64 LUT untukinteger
versi. Kedua versi banyak menggunakan rantai-bawa. Keduanya melaporkan kecepatan clock lebih dari 280MHz . Synthesizer ini cukup mampu membangun penggunaan yang baik dari rantai carry - saya diverifikasi secara visual dengan RTL viewer bahwa logika serupa dihasilkan dengan keduanya Jelas up-counter dengan komparator akan lebih besar, tetapi itu akan sama dengan bilangan bulat dan vektor lagi.Dibagi dengan 2 ** n penghitung
Disarankan oleh ajs410:
Arsitektur vektor
Arsitektur integer
Anda harus melompati beberapa simpai untuk menghindari hanya menggunakan
to_unsigned
dan kemudian mengambil bit yang jelas akan menghasilkan efek yang sama seperti di atas:Hasil
Dari segi kode, dalam hal ini,
vector
versinya jelas lebih baik!Dalam hal hasil sintesis, untuk contoh kecil ini, versi integer (seperti yang diprediksikan ajs410) memang menghasilkan 3 LUT tambahan sebagai bagian dari pembanding, saya terlalu optimis dengan synthesizer, meskipun ia bekerja dengan sepotong kode yang sangat dikaburkan!
Penggunaan lainnya
Vektor adalah kemenangan yang jelas ketika Anda ingin aritmatika membungkus (penghitung dapat dilakukan sebagai satu garis genap):
vs.
meskipun setidaknya jelas dari kode itu bahwa penulis bermaksud membungkus.
Sesuatu yang saya tidak gunakan dalam kode-nyata, tetapi merenungkan:
Fitur "pembungkus alami" juga dapat digunakan untuk "komputasi melalui luapan". Ketika Anda tahu bahwa output dari rantai penambahan / pengurangan dan perkalian dibatasi, Anda tidak harus menyimpan bit tinggi dari perhitungan perantara karena (dalam komplemen 2-s) ia akan keluar "dalam pencucian" pada saat Anda mencapai output. Saya diberitahu bahwa makalah ini berisi bukti tentang ini, tetapi tampak agak padat bagi saya untuk membuat penilaian cepat! Teori Penambahan dan Kelimpahan Komputer - HL Garner
Menggunakan
integer
s dalam situasi ini akan menyebabkan kesalahan simulasi ketika dibungkus, meskipun kita tahu mereka akan membukanya pada akhirnya.Dan seperti yang ditunjukkan Philippe, ketika Anda membutuhkan angka yang lebih besar dari 2 ** 31 Anda tidak punya pilihan selain menggunakan vektor.
sumber
variable c : unsigned(32 downto 0);
... bukankahc
variabel 33 bit?Saat menulis VHDL, saya sangat merekomendasikan menggunakan std_logic_vector (slv) daripada integer (int) untuk SIGNALS . (Di sisi lain, menggunakan int untuk generik, beberapa konstanta, dan beberapa variabel bisa sangat berguna.) Sederhananya, jika Anda mendeklarasikan sinyal tipe int, atau harus menentukan rentang untuk integer maka Anda mungkin melakukan sesuatu yang salah.
Masalah dengan int adalah bahwa programmer VHDL tidak tahu apa representasi logika internal dari int, sehingga kami tidak dapat memanfaatkannya. Sebagai contoh, jika saya mendefinisikan int kisaran 1 hingga 10, saya tidak tahu bagaimana kompiler mengkodekan nilai-nilai itu. Semoga itu akan dikodekan sebagai 4 bit, tetapi kita tidak tahu banyak tentang itu. Jika Anda dapat menyelidiki sinyal di dalam FPGA itu mungkin dikodekan sebagai "0001" menjadi "1010", atau dikodekan sebagai "0000" menjadi "1001". Mungkin juga dikodekan dengan cara yang sama sekali tidak masuk akal bagi kita manusia.
Sebaliknya, kita hanya harus menggunakan slv daripada int, karena dengan demikian kita memiliki kontrol atas pengkodean dan juga memiliki akses langsung ke bit individu. Memiliki akses langsung itu penting, seperti yang akan Anda lihat nanti.
Kita bisa memberikan int ke slv kapan pun kita membutuhkan akses ke bit individual, tetapi itu menjadi sangat berantakan, sangat cepat. Itu seperti mendapatkan yang terburuk dari kedua dunia alih-alih yang terbaik dari kedua dunia. Kode Anda akan sulit untuk dioptimalkan oleh kompiler, dan hampir mustahil untuk Anda baca. Saya tidak merekomendasikan ini.
Jadi, seperti yang saya katakan, dengan slv Anda memiliki kontrol atas penyandian bit dan akses langsung ke bit. Jadi apa yang dapat Anda lakukan dengan ini? Saya akan menunjukkan beberapa contoh. Katakanlah Anda perlu mengeluarkan pulsa setiap 4.294.000.000 jam. Inilah cara Anda melakukan ini dengan int:
Dan kode yang sama menggunakan slv:
Sebagian besar kode ini identik antara int dan slv, setidaknya dalam arti ukuran dan kecepatan logika yang dihasilkan. Tentu saja satu menghitung mundur dan yang lainnya menghitung mundur, tetapi itu tidak penting untuk contoh ini.
Perbedaannya ada pada "garis penting".
Dengan contoh int, ini akan menghasilkan komparator 32-input. Dengan 4-Input LUT yang digunakan Xilinx Spartan-3, ini akan membutuhkan 11 LUT dan 3 level logika. Beberapa kompiler mungkin mengubahnya menjadi pengurangan yang akan menggunakan rantai carry dan span setara dengan 32 LUT tetapi mungkin berjalan lebih cepat dari 3 level logika.
Dengan contoh slv, tidak ada perbandingan 32-bit sehingga "nol LUT, nol tingkat logika". Satu-satunya penalti adalah bahwa counter kami adalah satu bit ekstra. Karena waktu tambahan untuk penghitung ekstra ini semuanya ada dalam rantai penampung, ada penundaan waktu tambahan "hampir nol".
Tentu saja ini adalah contoh ekstrem, karena kebanyakan orang tidak akan menggunakan penghitung 32-bit dengan cara ini. Itu berlaku untuk penghitung yang lebih kecil, tetapi perbedaannya akan kurang dramatis meskipun masih signifikan.
Ini hanya satu contoh bagaimana memanfaatkan slv over int untuk mendapatkan pengaturan waktu yang lebih cepat. Ada banyak cara lain untuk memanfaatkan slv - hanya dibutuhkan beberapa imajinasi.
Pembaruan: Menambahkan hal-hal untuk menanggapi komentar Martin Thompson tentang penggunaan int dengan "if (count-1) <0"
(Catatan: Saya berasumsi Anda bermaksud "jika menghitung <0", karena itu akan membuatnya lebih setara dengan versi slv saya dan menghapus kebutuhan untuk pengurangan tambahan itu.)
Dalam beberapa keadaan ini mungkin menghasilkan implementasi logika yang dimaksud tetapi tidak dijamin berfungsi sepanjang waktu. Itu akan tergantung pada kode Anda dan bagaimana kompiler Anda mengkodekan nilai int.
Bergantung pada kompiler Anda, dan bagaimana Anda menentukan rentang int Anda, sangat mungkin bahwa nilai int nol tidak menyandikan ke vektor bit "0000 ... 0000" ketika membuatnya menjadi logika FPGA. Agar variasi Anda berfungsi, itu harus disandikan ke "0000 ... 0000".
Misalnya, katakanlah Anda menetapkan int untuk memiliki rentang -5 hingga +5. Anda mengharapkan nilai 0 dikodekan menjadi 4 bit seperti "0000", dan +5 sebagai "0101" dan -5 sebagai "1011". Ini adalah skema pengkodean dua-pelengkap khas.
Tetapi jangan berasumsi bahwa kompiler akan menggunakan dua-pelengkap. Meskipun tidak biasa, komplemen satu dapat menghasilkan logika "lebih baik". Atau, kompiler dapat menggunakan semacam pengkodean "bias" di mana -5 dikodekan sebagai "0000", 0 sebagai "0101", dan +5 sebagai "1010".
Jika pengkodean int adalah "benar" maka kompiler kemungkinan akan menyimpulkan apa yang harus dilakukan dengan carry bit. Tetapi jika itu salah maka logika yang dihasilkan akan mengerikan.
Mungkin saja menggunakan int dengan cara ini bisa menghasilkan ukuran dan kecepatan logika yang masuk akal, tetapi itu bukan jaminan. Beralih ke kompiler yang berbeda (XST ke Sinopsis misalnya), atau pergi ke arsitektur FPGA yang berbeda dapat menyebabkan hal yang salah terjadi.
Belum ditandatangani / ditandatangani vs slv adalah debat lain. Anda dapat berterima kasih kepada komite Pemerintah AS karena telah memberi kami begitu banyak pilihan dalam VHDL. :) Saya menggunakan slv karena itu adalah standar untuk antarmuka antara modul dan inti. Selain itu, dan beberapa kasus lain dalam simulasi, saya tidak berpikir ada manfaat besar untuk menggunakan slv lebih dari yang ditandatangani / tidak ditandatangani. Saya juga tidak yakin apakah sinyal tri-menyatakan dukungan yang ditandatangani / tidak ditandatangani.
sumber
if (count-1) < 0
saya pikir synthesizer akan menyimpulkan bit melaksanakan dan menghasilkan banyak sirkuit yang sama dengan contoh slv Anda. Juga, seharusnya kita tidak menggunakanunsigned
tipe ini hari ini :)Saran saya adalah mencoba keduanya, dan kemudian lihat sintesis, peta, dan laporan tempat-dan-rute. Laporan-laporan ini akan memberi tahu Anda dengan tepat berapa banyak LUT yang digunakan setiap pendekatan, mereka juga akan memberi tahu Anda kecepatan maksimum di mana logika dapat beroperasi.
Saya setuju dengan David Kessner bahwa Anda berada di bawah kekuasaan rantai alat Anda, dan tidak ada jawaban "benar". Sintesis adalah ilmu hitam dan cara terbaik untuk mengetahui apa yang terjadi adalah dengan cermat dan cermat membaca laporan yang dihasilkan. Alat-alat Xilinx bahkan memungkinkan Anda untuk melihat di dalam FPGA, sampai bagaimana setiap LUT diprogram, bagaimana rantai pembawa terhubung, bagaimana kain sakelar menghubungkan semua LUT, dll.
Untuk contoh dramatis lain dari pendekatan Mr. Kessner, bayangkan Anda ingin memiliki beberapa frekuensi clock pada 1/2, 1/4, 1/8, 1/16, dll. Anda bisa menggunakan integer yang terus-menerus menghitung setiap siklus, dan kemudian memiliki beberapa komparator terhadap nilai integer itu, dengan masing-masing output komparator membentuk divisi clock yang berbeda. Bergantung pada jumlah pembanding, fanout bisa menjadi sangat besar dan mulai mengkonsumsi LUT tambahan hanya untuk buffering. Pendekatan SLV hanya akan mengambil setiap bit individu dari vektor sebagai output.
sumber
Salah satu alasan yang jelas adalah bahwa ditandatangani dan tidak ditandatangani memungkinkan nilai lebih besar dari integer 32 bit. Itu adalah cacat dalam desain bahasa VHDL, yang tidak penting. Versi baru VHDL dapat memperbaikinya, membutuhkan nilai integer untuk mendukung ukuran arbitrer (mirip dengan BigInt Java).
Selain itu, saya sangat tertarik untuk mendengar tentang tolok ukur yang berkinerja berbeda untuk bilangan bulat dibandingkan dengan vektor.
BTW, Jan Decalukami menulis esai yang bagus tentang ini: Ints ini dibuat untuk Countin '
sumber