Conversão e Cast
Posted on qui 05 setembro 2019 in vhdl • 3 min read
VHDL é uma linguagem fortemente tipada, o que na prática significa que você não pode atribuir um sinal de um tipo a outro diretamente.
No entanto, conversões entre tipos relacionados são muito comuns, então apresentaremos aqui algumas formas de conversão.
Tipos agregados
Há uma diferença muito grande entre tipos agregados e nativos.
Uma das conversões mais comuns que existem em VHDL é de/para inteiros, pois estes são utilizados como indexadores ou comparadores com literais constantes. O inteiro no entanto, é um tipo nativo do VHDL enquanto que outros tipos, como unsigned
ou signed
são tipos compostos, considerados agregados (são como vetores de bits com um significado especial). Os tipos vetores, em especial o bit_vector
e o std_logic_vector
também são vetores de bits, porém não tem nenhum significado associado fora os definidos pelo seus respectivos tipos base.
Para converter entre um tipo numérico e um agregado, é necessário uma função de conversão pois são tipos diferentes dentro da linguagem. Já entre dois tipos numéricos ou entre dois tipos agregados, é necessário somente um cast. Exceto pelo bit_vector
, todos os outros tipos e conversões precisam ser descritos, porém há bibliotecas padronizadas para todas as conversões possíveis.
Tipo | Biblioteca | Categoria |
---|---|---|
bit |
nativo | Simples |
bit_vector |
nativo | Agregado |
std_logic |
ieee.std_logic_1164 |
Enumerado |
std_logic_vector |
ieee.std_logic_1164 |
Agregado |
Ao incluir a biblioteca ieee.std_logic_1164
, passamos a ter acesso aos tipos baseados em std_logic
. As bibliotecas padronizadas com as rotinas de conversão são as ieee.numeric_std
para os derivados de std_logic
, e a ieee.numeric_bit
para os tipos derivados do bit
.
As funções de conversão disponíveis na numeric_bit
podem ser vista na figura:
Em cinza as células que dispensam de conversão (mesmo tipo), amarelo as que requerem uma função de conversão específica, verde as que dispensam a conversão mas precisam de um cast para mudar a semântica de interpretação. Em vermelho as conversões indisponíveis diretamente.
De integer
para qualquer um dos outros tipos, temos que usar uma função de conversão (em amarelo na tabela), que começam com to_
. São elas:
I to_integer(S)
: recebe umsigned
e retorna um inteiro;I to_integer(U)
: recebe umunsigned
e retorna um inteiro;S to_signed(I,S'lenght)
: recebe um inteiro e retorna umsigned
, segundo parâmetro é o tamanho dosigned
;U to_unsigned(I,U'lenght)
: recebe um inteiro e retorna umunsigned
, segundo parâmetro é o tamanho dounsigned
;
Nas conversões para inteiro, o inteiro resultante terá o tamanho necessário para acomodar o tipo de origem (normalmente um bit a mais), mas a definição final do tamanho do inteiro depende do sintetizador. Nas conversões de inteiros, o tamanho do retorno deve ser especificado pois um inteiro tem tamanho indefinido, mas os vetores tem tamanho definido (veja o post sobre tipos de dados para limitações dos simuladores/sintetizadores).
Os demais tipos são todos vetores de bits, portanto não precisamos converter o tipo mas sim fazer um cast, ou seja, ordenar o sintetizador a interpretar os dados com uma semântica diferente. O cast pode ser feito usando o tipo de destino e colocando a origem entre parênteses:
V bit_vector(S)
: recebe umsigned
e o interpreta como umbit_vector
;V bit_vector(U)
: recebe umunsigned
e o interpreta como umbit_vector
;S signed(V)
: recebe umbit_vector
e o interpreta comosigned
;U unsigned(V)
: recebe umbit_vector
e o interpreta comounsigned
;
Note que isto não é uma função de conversão, o sintetizador apenas interpretará aquele conjunto de bits (agregado) com uma semântica diferente do tipo original declarado.
Para resumir, veja o diagrama abaixo:
O diagrama acima foi inspirado no diagrama do site BitWeenie para std_logic
. Se o tipo base que você está usando e o std_logic
, você deve incluir a biblioteca numeric_std
pois as conversões de/para este tipo estão nesta biblioteca.
Contribuições
- 25/set/2020: Arthur Lopes corrigiu o tipo do
std_logic
na tabela e obit_vector(U)
no diagrama. - 27/set/2021: O monitor Joaquin Lorenzo Pereira Condori reportou um erro no diagrama de conversão (de unsigned para integer).