VHDL: Konversi dari tipe INTEGER ke STD_LOGIC_VECTOR

28

Saya membangun penghitung mod-16, dan hasil keluarannya adalah INTEGER (semua contoh yang saya lihat menggunakan INTEGER).

Saya membuat dekoder hex-to-7-segment-display, dan inputnya adalah STD_LOGIC_VECTOR (tulis seperti itu karena mudah untuk memetakan tabel kebenaran).

Saya ingin menghubungkan output dari penghitung ke input decoder, tapi saya mendapatkan kesalahan 'ketik ketidakcocokan' ketika mencoba mengkompilasi di QuartusII.

Apakah ada cara untuk mengkonversi dari tipe INTEGER ke tipe STD_LOGIC_VECTOR dalam daftar VHDL?

J. Polfer
sumber

Jawaban:

20

Seperti yang orang lain katakan, gunakan ieee.numeric_std, tidak pernah ieee.std_logic_unsigned, yang sebenarnya bukan paket IEEE.

Namun, jika Anda menggunakan alat dengan dukungan VHDL 2008, Anda dapat menggunakan paket baru ieee.numeric_std_unsigned, yang pada dasarnya membuat std_logic_vectorberperilaku seperti tidak ditandatangani.

Juga, karena saya tidak melihatnya secara eksplisit, berikut ini contoh kode aktual untuk mengkonversi dari integer (unsigned) menjadi std_logic_vector:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));
wjl
sumber
16

Seperti yang dikatakan LoneTech, use ieee.numeric_stdadalah temanmu. Anda dapat mengkonversi std_logic_vectorke integer, tapi Anda harus dilemparkan sebagai signedatau unsignedpertama (sebagai compiler tidak tahu yang Anda maksud). VHDL adalah bahasa yang sangat diketik. Saya telah menulis lebih banyak tentang hal ini di blog saya

Pada dasarnya, saya akan mengubah konverter 7seg Anda untuk mengambil integer(atau sebenarnya natural, mengingat bahwa itu hanya akan berurusan dengan angka positif) - konversi kemudian pencarian array sederhana. Siapkan array konstan dengan konversi di dan hanya indeks ke dalamnya dengan integer yang Anda gunakan pada entitas sebagai input.

Martin Thompson
sumber
Terima kasih untuk ini. Saya sangat menghargai komentar Anda. Saya berada dalam posisi TA semacam itu, belajar VHDL untuk membantu seorang profesional memulai yang sedikit goyah pada konsep pemrograman. Saya akan menyampaikan info Anda kepadanya - buku teks yang kami gunakan tidak menggali pertanyaan 'moralitas' VHDL.
J. Polfer
1
Ini kurang dari masalah 'moralitas' daripada itu adalah jaminan konsistensi. Angka numeric_std lib adalah standar nyata yang dilembagakan oleh IEEE, sedangkan perpustakaan std_logic_unsigned dibuat oleh vendor, dan diadopsi di industri tanpa definisi formal yang nyata. Tidak ada jaminan kompatibilitas lintas-vendor dengan lib non-standar, meskipun biasanya berfungsi dengan baik. Ini adalah bentuk yang baik untuk beralih ke standar sekarang.
MattG
1

Katakanlah penghitung 4-bit Anda memiliki output INTEGER SOME_INTEGER, dan Anda ingin mengubahnya menjadi STD_LOGIC_VECTOR 4-bit

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

Anda juga dapat menggunakan ini untuk menginisialisasi vektor dengan angka yang bermakna

SOME_VECTOR <= conv_std_logic_vector(9, 4); -- instead of "1001"

Saya pikir Anda mungkin perlu menambahkan "gunakan IEEE.STD_LOGIC_ARITH.ALL;" dan / atau STD_LOGIC_UNSIGNED.

Operasi pelengkap adalah conv_integer (vektor). Saya suka menggunakan ini ketika saya melakukan perbandingan. Jadi saya mungkin menyatakan

constant SOME_CONSTANT : integer := 999;

Dan kemudian, nanti, saya bisa menggunakan ini dalam pernyataan if

if (conv_integer(SOME_VECTOR)=SOME_CONSTANT)
  then OTHER_VECTOR <= (others => '0');
end if;

EDIT: Anda tidak perlu mendeklarasikan variabel sebagai Integer. Coba ubah deklarasi menjadi std_logic_vector sebagai gantinya. Operator + dan - bekerja pada std_logic_vectors.

ajs410
sumber
3
Tolong jangan lakukan ini! Gunakan numeric_std (lihat jawaban LoneTech dan saya)
Martin Thompson
Jika Anda memiliki cara yang lebih baik untuk melakukannya, itu baik-baik saja, tetapi saran saya berfungsi, jadi saya pikir down-vote Anda tidak perlu. Saya telah menggunakan std_logic_arith selama bertahun-tahun dan saya tidak pernah memiliki masalah dengannya. Saya pikir kekhawatiran tentang vendor yang mengubah implementasi mereka tidak berdasar; vendor apa yang waras mereka akan berisiko melanggar desain pelanggan mereka?
ajs410
1
Anda sudah memiliki jawaban untuk vendor apa yang akan dengan sengaja meletakkan barang-barang khusus vendor di namespace IEEE. Itu tetap kasar, terutama ketika berhadapan dengan nilai-nilai yang ditandatangani dan tidak ditandatangani.
Yann Vernier
"Operator + dan - bekerja pada std_logic_vectors." AFAIK, mereka tidak bekerja, kecuali saya salah mengerti maksud Anda. biasanya perlu dilemparkan ke jenis yang memegang data yang ditandatangani / tidak ditandatangani terlebih dahulu.
stanri
1

Anda mungkin tertarik menggunakan jenis unsigneddan signeddari ieee.numeric_std. Mereka kompatibel dengan std_logic_vector, tetapi memiliki interpretasi numerik (biner atau 2-komplemen). Ada juga opsi untuk menempatkan interpretasi seperti itu std_logic_vector, tetapi ini tidak dianjurkan .

Yann Vernier
sumber
0

Seperti jawaban utama mengatakan, metode yang disarankan adalah sebagai berikut:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

Namun, saya ingin menguraikan tentang mengapa ini direkomendasikan, dan mengapa VHDL memiliki cara yang tampaknya berbelit-belit untuk mengubah bilangan bulat menjadi std_logic_vectors.

Turun ke bagaimana jenis ini dilihat oleh alat.

Standard_logic_vector secara harfiah adalah sekelompok 1s atau 0s. Saya punya 10001. Nomor apa ini? Yah, itu tergantung. Apakah ditandatangani atau tidak ditandatangani? SLV tidak tahu atau tidak peduli. Berapa banyak bit? Nah, berapa lama SLV Anda?

Integer ditandatangani, dan biasanya 32 bit (jika saya ingat dengan benar).

Tahap 1: Buat bilangan bulat saya lebih pendek, dan tidak ditandatangani. Itu bagian ini:

to_unsigned(my_int, my_slv'length));

"Saya memiliki bilangan bulat ini, saya ingin itu tidak ditandatangani, dan saya ingin itu sesuai dengan panjang SLV saya."

Tahap 2: Lalu, ambil bit-bit itu dan gunakan untuk menggerakkan my_slv.

my_slv <= std_logic_vector(...)

"Ambil bit ini, dan gunakan untuk menggerakkan slv saya"

(Catatan tentang terminologi. A <= BDalam VHDL dibaca keras-keras karena "A digerakkan oleh B")

Gabungan, ini membuat Anda:

my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

Ketika datang dari latar belakang pemrograman tradisional, sangat mudah terjebak dalam cara berpikir pemrograman. Tetapi dalam VHDL kode yang Anda tulis memiliki implikasi fisik dalam perangkat keras. Mengetahui mengapa metode ini bekerja dan direkomendasikan adalah satu langkah lebih dekat untuk memikirkan apa yang Anda tulis dalam istilah perangkat keras.

Kiat bonus: fungsi yang diawali oleh to_ adalah fungsi yang mempersingkat / mengubah operan. Mereka membuat mereka tanpa tanda tangan atau panjang tertentu atau keduanya. Inilah sebabnya mengapa to_unsigned mengharuskan Anda menentukan panjangnya. Fungsi tanpa to_ (std_logic_vector lurus (...) dalam contoh ini) digunakan ketika jenis sudah langsung kompatibel. "Ambil bit-bit ini dan masukkan mereka dalam tipe ini, tidak perlu modifikasi". Ini tidak memiliki argumen panjang karena kedua belah pihak sudah sama. Jadi ketika membangun hal-hal seperti ini, saya tidak perlu mencarinya, saya hanya berpikir tentang bagaimana saya mengubah data.

stanri
sumber
0

Untuk mengonversi integer ke std_logic_vector Anda memiliki beberapa opsi. Menggunakan numeric_std:

vect <= std_logic_vector( to_unsigned( your_int, vect'length));

atau

vect <= std_logic_vector( to_signed( your_int, vect'length));

Menggunakan std_logic_arith:

vect <= conv_std_logic_vector( your_int, vect'length);

std_logic_arith bukan merupakan standar ieee, tetapi sebagian besar alat mengkompilasinya ke perpustakaan IEEE dan banyak digunakan.

Craig
sumber