VHDL: convertendo de um tipo INTEGER para um STD_LOGIC_VECTOR


28

Eu construí um contador mod-16, e o resultado da saída é um INTEGER (todos os exemplos que vi usados ​​INTEGER).

Eu construí um decodificador de exibição hexadecimal para 7 segmentos e sua entrada é um STD_LOGIC_VECTOR (escrevi dessa maneira porque era fácil mapear a tabela verdade).

Gostaria de conectar a saída do contador à entrada do decodificador, mas recebo erros de 'incompatibilidade de tipo' ao tentar compilar no QuartusII.

Existe uma maneira de converter de um tipo INTEGER para um tipo STD_LOGIC_VECTOR em uma listagem VHDL?

Respostas:


20

Como outros disseram, use ieee.numeric_stdnunca ieee.std_logic_unsigned, o que não é realmente um pacote IEEE.

No entanto, se você estiver usando ferramentas com suporte ao VHDL 2008, poderá usar o novo pacote ieee.numeric_std_unsigned, que basicamente se std_logic_vectorcomporta como não assinado.

Além disso, como eu não o vi explicitamente, aqui está um exemplo de código real para converter de um número inteiro (não assinado) em um std_logic_vector:

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

16

Como LoneTech diz, use ieee.numeric_stdé seu amigo. Você pode converter um std_logic_vectorem um integer, mas precisará convertê- lo como signedou unsignedprimeiro (pois o compilador não tem idéia do que você quer dizer). VHDL é uma linguagem fortemente tipada. Eu escrevi mais sobre esse assunto no meu blog

Fundamentalmente, eu mudaria o seu conversor 7seg para incluir um integer(ou, na verdade natural, um , já que ele lida apenas com números positivos) - a conversão é, então, uma simples pesquisa de array. Configure um array constante com as conversões e apenas indexe nele com o número inteiro que você usa na entidade como entrada.


Obrigado por isso. Eu aprecio muito seus comentários. Eu estava em uma posição de AT, aprendendo VHDL para ajudar um professor a começar, que era um pouco instável em conceitos de programação. Vou passar suas informações para ele - o livro que usamos não se aprofundou nas questões de 'moralidade' do VHDL.
J.Julfer

1
É menos uma questão de 'moralidade' do que uma garantia de consistência. A numeric_std lib é um padrão real instituído pelo IEEE, enquanto a biblioteca std_logic_unsigned foi composta por um fornecedor e adotada no setor sem nenhuma definição formal real. Não há garantia de compatibilidade entre fornecedores com as bibliotecas não padrão, embora normalmente funcione bem. É uma boa forma de passar para o padrão agora.
MattG

1

Digamos que seu contador de 4 bits tenha uma saída INTEGER SOME_INTEGER e você queira convertê-lo em um STD_LOGIC_VECTOR de 4 bits

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

Você também pode usar isso para inicializar vetores com números significativos

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

Eu acho que você pode precisar adicionar "use IEEE.STD_LOGIC_ARITH.ALL;" e / ou STD_LOGIC_UNSIGNED.

A operação complementar é conv_integer (vetor). Eu gosto de usar isso quando faço comparações. Então eu posso declarar

constant SOME_CONSTANT : integer := 999;

E então, mais tarde, eu posso usar isso em uma instrução if

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

EDIT: você não precisa declarar a variável como um número inteiro. Tente alterar a declaração para std_logic_vector. Os operadores + e - trabalham em std_logic_vectors.


3
Por favor, não faça isso! Use numeric_std (consulte LoneTech e minhas respostas)
Martin Thompson

Se você tem uma maneira melhor de fazer isso, tudo bem, mas minha sugestão funciona, então eu acho que seu voto negativo foi desnecessário. Eu uso std_logic_arith há anos e nunca tive problemas com isso. Eu acho que os receios sobre os fornecedores mudarem suas implementações são infundados; que fornecedor, em sã consciência, se arriscará a quebrar o design de seus clientes?
ajs410

1
Você já tem uma resposta para qual fornecedor voluntariamente colocará itens específicos do fornecedor no espaço de nomes do IEEE. Ele permanece bruto, principalmente ao lidar com valores assinados e não assinados.
Yann Vernier #

"Os operadores + e - trabalham em std_logic_vectors." AFAIK, eles não funcionam, a menos que eu entenda mal o seu significado. geralmente é necessário converter para um tipo que contenha dados assinados / não assinados primeiro.
stanri

1

Você pode estar interessado em usar os tipos unsignede signedde ieee.numeric_std. Eles são compatíveis com std_logic_vector, mas têm uma interpretação numérica (binária ou com 2 complementos). Há também a opção de colocar essa interpretação std_logic_vector, mas isso não é recomendado .


0

Como a resposta principal diz, o método recomendado é o seguinte:

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

No entanto, gostaria de explicar por que isso é recomendado e por que o VHDL tem uma maneira aparentemente complicada de converter números inteiros em std_logic_vectors.

Tudo se resume a como esses tipos são visualizados pelas ferramentas.

Um standard_logic_vector é literalmente um monte de 1s ou 0s. Eu tenho 10001. Que número é esse? Bem, isto depende. É assinado ou não assinado? O SLV não sabe nem se importa. Quantos bits? Bem, quanto tempo dura o seu SLV?

Um número inteiro é assinado e, geralmente, 32 bits (se bem me lembro).

Etapa 1: Tornar meu número inteiro mais curto e sem sinal. Essa é essa parte:

to_unsigned(my_int, my_slv'length));

"Eu tenho esse número inteiro, quero que ele não seja assinado e quero que ele caiba no comprimento da minha SLV".

Etapa 2: Pegue esses bits e use-os para conduzir o my_slv.

my_slv <= std_logic_vector(...)

"Pegue esses bits e use-os para dirigir meu slv"

(Uma observação sobre terminologia. A <= BEm VHDL é lida em voz alta como "A é dirigido por B")

Combinado, você recebe:

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

Quando vem de um background de programação tradicional, é muito fácil ficar preso em uma maneira de pensar em programação. Mas em VHDL o código que você escreve tem implicações físicas no hardware. Saber por que esse método funciona e é recomendado está a um passo de pensar no que você está escrevendo em termos de hardware.

Dica bônus: funções prefixadas por to_ são aquelas que reduzem / alteram os operandos. Eles os fazem sem assinatura ou com um certo comprimento ou ambos. É por isso que to_unsigned exige que você especifique o comprimento. As funções sem to_ (straight std_logic_vector (...) neste exemplo) são usadas quando os tipos já são diretamente compatíveis. "Pegue esses bits e encha-os nesse tipo, não são necessárias modificações". Estes não têm um argumento de comprimento porque os dois lados já são os mesmos. Portanto, ao construir coisas como essa, não preciso procurar, apenas penso em como estou alterando os dados.


0

Para converter um número inteiro em std_logic_vector, você tem várias opções. Usando numeric_std:

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

ou

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

Usando std_logic_arith:

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

std_logic_arith não é um padrão ieee, mas a maioria das ferramentas o compila na biblioteca IEEE e é amplamente utilizado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.