VHDL: Konwersja typu INTEGER na STD_LOGIC_VECTOR

28

Zbudowałem licznik mod-16, a wynikiem wyjściowym jest INTEGER (wszystkie przykłady, które widziałem, użyły INTEGER).

Zbudowałem dekoder szesnastkowy na 7-segmentowy, a jego wejściem jest STD_LOGIC_VECTOR (napisałem to w ten sposób, ponieważ łatwo było zmapować tabelę prawdy).

Chciałbym podłączyć wyjście licznika do wejścia dekodera, ale dostaję błędy „niezgodności typów” podczas próby kompilacji w QuartusII.

Czy istnieje sposób konwersji z typu INTEGER na typ STD_LOGIC_VECTOR na liście VHDL?

J. Polfer
źródło

Odpowiedzi:

20

Jak powiedzieli inni, używaj ieee.numeric_std, nigdy ieee.std_logic_unsigned, co tak naprawdę nie jest pakietem IEEE.

Jeśli jednak korzystasz z narzędzi obsługujących VHDL 2008, możesz użyć nowego pakietu ieee.numeric_std_unsigned, który zasadniczo std_logic_vectorzachowuje się jak bez znaku.

Ponadto, ponieważ nie widziałem tego wyraźnie, oto przykładowy kod do konwersji z (niepodpisanej) liczby całkowitej na std_logic_vector:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));
wjl
źródło
16

Jak mówi LoneTech, use ieee.numeric_stdjest twoim przyjacielem. Możesz przekonwertować a std_logic_vectorna integer, ale będziesz musiał rzucić go jako signedlub jako unsignedpierwszy (ponieważ kompilator nie ma pojęcia, co masz na myśli). VHDL jest silnie napisanym językiem. Mam napisany więcej na ten temat na moim blogu

Zasadniczo zmieniłbym twój konwerter 7seg na integer(lub właściwie natural, biorąc pod uwagę, że będzie on obsługiwał tylko liczby dodatnie) - konwersja jest wtedy prostym wyszukiwaniem tablicy. Skonfiguruj stałą tablicę z konwersjami i po prostu zindeksuj ją za pomocą liczby całkowitej, której użyjesz na encji jako danych wejściowych.

Martin Thompson
źródło
Dzięki za to. Bardzo doceniam twoje komentarze. Byłem w pewnym sensie na stanowisku TA, ucząc się VHDL, aby pomóc profesorowi w rozpoczęciu pracy, który był trochę niepewny przy programowaniu. Przekażę mu twoje informacje - użyty przez nas podręcznik nie zagłębił się w pytania „moralności” VHDL.
J. Polfer,
1
Jest to mniej kwestia „moralności” niż gwarancja spójności. Biblioteka numeric_std jest prawdziwym standardem ustanowionym przez IEEE, natomiast biblioteka std_logic_unsigned została stworzona przez dostawcę i przyjęta w branży bez żadnej rzeczywistej definicji formalnej. Nie ma gwarancji zgodności między dostawcami z niestandardowymi bibliotekami lib, choć zwykle działa dobrze. Jednak teraz jest to dobra forma, aby przejść do standardu.
MattG
1

Powiedzmy, że twój 4-bitowy licznik miał wyjście INTEGER SOME_INTEGER i chciałeś go przekonwertować na 4-bitowy STD_LOGIC_VECTOR

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

Można go również użyć do zainicjowania wektorów znaczącymi liczbami

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

Myślę, że może być konieczne dodanie „użyj IEEE.STD_LOGIC_ARITH.ALL;” i / lub STD_LOGIC_UNSIGNED.

Operacją uzupełniającą jest conv_integer (wektor). Lubię tego używać, kiedy dokonuję porównań. Więc mógłbym zadeklarować

constant SOME_CONSTANT : integer := 999;

A potem mogę użyć tego w instrukcji if

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

EDYCJA: Nie powinno być konieczne deklarowanie zmiennej jako liczby całkowitej. Zamiast tego spróbuj zmienić deklarację na std_logic_vector. Operatory + i - działają na wektorach std_logic_vectors.

ajs410
źródło
3
Proszę nie rób tego! Użyj numeric_std (patrz LoneTech i moje odpowiedzi)
Martin Thompson,
Jeśli masz lepszy sposób, aby to zrobić, to dobrze, ale moja sugestia działa, więc uważam, że twoje głosowanie w dół było niepotrzebne. Używam std_logic_arith od lat i nigdy nie miałem z tym żadnych problemów. Myślę, że obawy przed zmianami implementacji przez dostawców są bezpodstawne; Który sprzedawca przy zdrowych zmysłach ryzykuje złamaniem projektów swoich klientów?
ajs410,
1
Masz już odpowiedź na pytanie, który sprzedawca dobrowolnie umieści określone rzeczy w przestrzeni nazw IEEE. Pozostaje prymitywny, szczególnie w przypadku wartości podpisanych i niepodpisanych.
Yann Vernier
„Operatory + i - działają na wektorach std_logic_vectors.” AFAIK, nie działają, chyba że źle zrozumiem twoje znaczenie. zwykle konieczne jest rzutowanie na typ, który najpierw przechowuje podpisane / niepodpisane dane.
stanri
1

Możesz być zainteresowany korzystaniem z typów unsignedi signedod ieee.numeric_std. Są kompatybilne std_logic_vector, ale mają interpretację numeryczną (dwójkową lub 2-dopełniającą). Istnieje również opcja wprowadzenia takiej interpretacji std_logic_vector, ale nie jest to zalecane .

Yann Vernier
źródło
0

Jak głosi główna odpowiedź, zalecana metoda jest następująca:

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

Chciałbym jednak wyjaśnić, dlaczego jest to zalecane i dlaczego VHDL ma tak pozornie skomplikowany sposób przekształcania liczb całkowitych na wektory standardowe.

Wszystko sprowadza się do tego, jak narzędzia te postrzegają te typy.

Vector_logic_vector to dosłownie kilka zer lub jedynek. Mam 10001. Jaki to numer? Cóż, to zależy. Czy jest podpisany czy niepodpisany? SLV nie wie ani nie obchodzi. Ile bitów? Jak długi jest twój SLV?

Liczba całkowita jest podpisana i zwykle 32 bity (jeśli dobrze pamiętam).

Etap 1: Spraw, aby moja liczba całkowita była krótsza i niepodpisana. To jest ta część:

to_unsigned(my_int, my_slv'length));

„Mam tę liczbę całkowitą, chcę, aby była bez znaku i chcę, aby pasowała do długości mojego SLV”.

Etap 2: Następnie weź te bity i użyj ich do sterowania my_slv.

my_slv <= std_logic_vector(...)

„Weź te bity i użyj ich, by prowadzić mój slv”

(Uwaga na temat terminologii. A <= BW VHDL jest odczytywana na głos, ponieważ „A kieruje B”)

W połączeniu daje to:

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

Pochodząc z tradycyjnego programowania, bardzo łatwo utknąć w programistycznym sposobie myślenia. Ale w VHDL kod, który piszesz, ma fizyczne implikacje sprzętowe. Wiedza, dlaczego ta metoda działa i jest zalecana, jest o krok bliżej do zastanowienia się nad tym, co piszesz w kategoriach sprzętowych.

Dodatkowa wskazówka: funkcje poprzedzone przez to_ to te, które skracają / zmieniają operandy. Sprawiają, że stają się niepodpisane, mają określoną długość lub oba. Dlatego to_unsigned wymaga określenia długości. Funkcje bez to_ (w tym przykładzie prosty std_logic_vector (...)) są używane, gdy typy są już bezpośrednio kompatybilne. „Weź te bity i włóż je do tego typu, nie wymaga modyfikacji”. Nie mają one argumentu długości, ponieważ obie strony są już takie same. Więc konstruując takie rzeczy, nie muszę tego sprawdzać, po prostu myślę o tym, jak zmieniam dane.

stanri
źródło
0

Aby przekonwertować liczbę całkowitą na std_logic_vector, masz kilka opcji. Za pomocą numeric_std:

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

lub

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

Za pomocą std_logic_arith:

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

std_logic_arith nie jest standardem ieee, ale większość narzędzi kompiluje go do biblioteki IEEE i jest szeroko stosowana.

Craig
źródło