VHDL: conversione da un tipo INTEGER a STD_LOGIC_VECTOR


28

Ho creato un contatore mod-16 e il risultato dell'uscita è un INTEGER (tutti gli esempi che ho visto hanno usato INTEGER).

Ho costruito un decodificatore con display esadecimale a 7 segmenti e il suo input è un STD_LOGIC_VECTOR (scritto in questo modo perché era facile mappare la tabella della verità).

Vorrei collegare l'output del contatore all'ingresso del decodificatore, ma ottengo errori di "tipo non corrispondente" quando provo a compilare in QuartusII.

C'è un modo per convertire da un tipo INTEGER a un tipo STD_LOGIC_VECTOR in un elenco VHDL?

Risposte:


20

Come altri hanno detto, usa ieee.numeric_stdmai ieee.std_logic_unsigned, che non è in realtà un pacchetto IEEE.

Tuttavia, se si utilizzano strumenti con supporto VHDL 2008, è possibile utilizzare il nuovo pacchetto ieee.numeric_std_unsigned, che in sostanza si std_logic_vectorcomporta come non firmato.

Inoltre, poiché non l'ho visto esplicitamente dichiarato, ecco un esempio di codice reale per convertire da un numero intero (non firmato) a std_logic_vector:

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

16

Come dice LoneTech, use ieee.numeric_stdè tuo amico. Puoi convertire a std_logic_vectorin integer, ma dovrai lanciarlo come signedo unsignedprima (poiché il compilatore non ha idea di cosa intendi). VHDL è un linguaggio fortemente tipizzato. Ho scritto di più su questo argomento sul mio blog

Fondamentalmente, cambierei il tuo convertitore 7seg per includere un integer(o effettivamente un natural, dato che si occuperà solo di numeri positivi) - la conversione è quindi una semplice ricerca di array. Imposta un array costante con le conversioni e indicizzalo con il numero intero che usi sull'entità come input.


Grazie per questo. Apprezzo molto i tuoi commenti. Ero in una sorta di posizione TA, imparando VHDL per aiutare un prof a iniziare che era un po 'scosso sui concetti di programmazione. Gli passerò le tue informazioni - il libro di testo che abbiamo usato non ha approfondito le domande sulla "moralità" del VHDL.
J. Polfer,

1
È meno un problema di "moralità" di quanto non sia una garanzia di coerenza. La libreria numeric_std è un vero standard istituito dall'IEEE, mentre la libreria std_logic_unsigned è stata creata da un fornitore e adottata nel settore senza una vera definizione formale. Non esiste alcuna garanzia di compatibilità tra venditori con le librerie non standard, sebbene in genere funzioni correttamente. È una buona forma passare ora allo standard ora.
MattG,

1

Supponiamo che il tuo contatore a 4 bit avesse un output INTEGER SOME_INTEGER e tu volessi convertirlo in un STD_LOGIC_VECTOR a 4 bit

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

Puoi anche usarlo per inizializzare i vettori con numeri significativi

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

Penso che potresti dover aggiungere "usa IEEE.STD_LOGIC_ARITH.ALL;" e / o STD_LOGIC_UNSIGNED.

L'operazione complementare è conv_integer (vettore). Mi piace usare questo quando faccio i confronti. Quindi potrei dichiarare

constant SOME_CONSTANT : integer := 999;

E poi, più tardi, posso usarlo in un'istruzione if

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

EDIT: non è necessario dichiarare la variabile come numero intero. Prova invece a cambiare la dichiarazione in std_logic_vector. Gli operatori + e - lavorano su std_logic_vectors.


3
Per favore, non farlo! Usa numeric_std (vedi LoneTech e le mie risposte)
Martin Thompson,

Se hai un modo migliore per farlo, va bene, ma il mio suggerimento funziona quindi penso che il tuo voto negativo non sia stato necessario. Ho usato std_logic_arith per anni e non ho mai avuto problemi con esso. Penso che i timori per i venditori che cambiano le loro implementazioni siano infondati; quale fornitore nella loro mente corretta rischierà di infrangere i progetti dei loro clienti?
ajs410,

1
Hai già una risposta a quale fornitore inserirà intenzionalmente elementi specifici del fornitore nello spazio dei nomi IEEE. Rimane rozzo, in particolare quando si tratta di valori firmati e non firmati.
Yann Vernier,

"Gli operatori + e - lavorano su std_logic_vectors." AFAIK, non funzionano, a meno che non fraintenda il tuo significato. di solito è necessario eseguire il cast su un tipo che contiene prima i dati firmati / non firmati.
Stanni,

1

Potresti essere interessato a utilizzare i tipi unsignede signedda ieee.numeric_std. Sono compatibili con std_logic_vector, ma hanno un'interpretazione numerica (binaria o complemento a 2). C'è anche la possibilità di inserire una simile interpretazione std_logic_vector, ma questo non è raccomandato .


0

Come dice la risposta principale, il metodo raccomandato è il seguente:

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

Tuttavia, vorrei approfondire il motivo per cui questo è raccomandato e perché VHDL ha un modo così apparentemente contorto di convertire numeri interi in std_logic_vectors.

Dipende da come questi tipi vengono visualizzati dagli strumenti.

Uno standard_logic_vector è letteralmente un gruppo di 1 o 0 secondi. Ho 10001. Che numero è questo? Beh, dipende. È firmato o non firmato? Questo SLV non lo sa e non gliene importa. Quanti bit? Bene, quanto dura il tuo SLV?

Un numero intero è firmato e di solito a 32 bit (se ricordo bene).

Fase 1: rendere il mio numero intero più breve e senza segno. Questa è questa parte:

to_unsigned(my_int, my_slv'length));

"Ho questo numero intero, voglio che sia senza segno e voglio che si adatti alla lunghezza del mio SLV."

Fase 2: Quindi, prendi quei bit e usali per guidare my_slv.

my_slv <= std_logic_vector(...)

"Prendi questi bit e usali per guidare il mio slv"

(Una nota sulla terminologia. A <= BIn VHDL viene letta ad alta voce come "A è guidato da B")

Combinato, questo ti dà:

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

Quando proviene da un background di programmazione tradizionale, è molto facile rimanere bloccati in un modo di pensare di programmazione. Ma in VHDL il codice che scrivi ha implicazioni fisiche nell'hardware. Sapere perché questo metodo funziona ed è consigliato è un passo in avanti verso pensare a ciò che stai scrivendo in termini hardware.

Suggerimento bonus: le funzioni precedute da to_ sono quelle che accorciano / modificano gli operandi. Li rendono non firmati o una certa lunghezza o entrambi. Questo è il motivo per cui to_unsigned richiede di specificare la lunghezza. Le funzioni senza to_ (straight std_logic_vector (...) in questo esempio) vengono utilizzate quando i tipi sono già direttamente compatibili. "Prendi questi bit e riempili in questo tipo, non sono necessarie modifiche". Questi non hanno un argomento lungo perché entrambe le parti sono già le stesse. Quindi, quando costruisco cose come questa, non ho bisogno di cercarle, penso solo a come sto cambiando i dati.


0

Per convertire un numero intero in std_logic_vector hai diverse opzioni. Usando numeric_std:

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

o

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

Utilizzando std_logic_arith:

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

std_logic_arith non è uno standard ieee, ma la maggior parte degli strumenti lo compila nella libreria IEEE ed è ampiamente usato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.