Como usar assinado e não assinado em VHDL
Os tipos assinados e não assinados em VHDL são vetores de bits, assim como o tipo std_logic_vector. A diferença é que, embora o std_logic_vector seja ótimo para implementar barramentos de dados, é inútil para realizar operações aritméticas.
Se você tentar adicionar qualquer número a um tipo std_logic_vector, ModelSim produzirá o erro de compilação:Nenhuma entrada viável para o operador infixo “+”. Isso porque o compilador não sabe interpretar essa coleção de bits que é o vetor.
Esta postagem do blog faz parte da série de tutoriais básicos de VHDL.
Devemos declarar nosso vetor como assinado ou não assinado para que o compilador o trate como um número.
A sintaxe para declarar sinais assinados e não assinados é:
signal <name> : signed(<N-bits> downto 0) := <initial_value>;
signal <name> : unsigned(<N-bits> downto 0) := <initial_value>;
Assim como com std_logic_vector, os intervalos podem ser
to
ou downto
qualquer intervalo. Mas declarar sinais com outros intervalos além de downto 0
é tão incomum, que gastar mais tempo com o assunto só serviria para nos confundir. O valor inicial é opcional, por padrão é 'U'
para todos os bits. Já estamos usando o
integer
type para operações aritméticas em tutoriais anteriores. Então, por que precisamos dos tipos assinados e não assinados? Para a maioria, os designers digitais gostam de ter mais controle de quantos bits um sinal realmente usa. Além disso, os valores assinados e não assinados são agrupados, enquanto o simulador lançará um erro em tempo de execução se um
integer
é incrementado além dos limites. Por fim, assinado e não assinado podem ter outros valores como 'U'
e 'X'
, enquanto os inteiros só podem ter valores numéricos. Esses meta-valores podem nos ajudar a descobrir erros em nosso design. Exercício
Neste vídeo, aprendemos como os sinais assinados e não assinados se comportam da mesma forma e como eles se comportam de maneira diferente:
O código final que criamos neste tutorial:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T12_SignedUnsignedTb is end entity; architecture sim of T12_SignedUnsignedTb is signal UnsCnt : unsigned(7 downto 0) := (others => '0'); signal SigCnt : signed(7 downto 0) := (others => '0'); signal Uns4 : unsigned(3 downto 0) := "1000"; signal Sig4 : signed(3 downto 0) := "1000"; signal Uns8 : unsigned(7 downto 0) := (others => '0'); signal Sig8 : signed(7 downto 0) := (others => '0'); begin process is begin wait for 10 ns; -- Wrapping counter UnsCnt <= UnsCnt + 1; SigCnt <= SigCnt + 1; -- Adding signals Uns8 <= Uns8 + Uns4; Sig8 <= Sig8 + Sig4; end process; end architecture;
A janela de forma de onda no ModelSim, ampliada nas partes interessantes:

Análise
A base de todos os sinais na forma de onda é definida como hexadecimal para que possamos compará-los igualmente.
No exemplo do contador de encapsulamento, vemos que os sinais assinados e não assinados se comportam exatamente da mesma maneira. Ambos
UnsCnt
e SigCnt
começam em 0 e são incrementados um a um até FF. Hex FF (decimal 255) é o maior valor que nossos sinais de 8 bits podem conter. Portanto, o próximo incremento envolve ambos de volta a 0. Criamos os dois sinais de 4 bits
Uns4
e Sig4
, e deu a ambos um valor inicial de “1000”. Podemos ver pela forma de onda que ambos são apenas hexadecimal 8 (binário 1000). Os dois últimos sinais de 8 bits que criamos foram
Uns8
e Sig8
. Podemos ver pela forma de onda que seus valores iniciais são 0, como seria de esperar. Mas a partir daí, eles se comportam de forma diferente! Aparentemente, os tipos assinados e não assinados fizeram a diferença ao adicionar dois sinais de comprimentos diferentes. Isso ocorre por causa de algo conhecido como extensão de sinal . Adicionar números positivos ou negativos armazenados em vetores de igual comprimento é a mesma operação na lógica digital. Isso ocorre por causa de como o complemento de dois funciona. Se os vetores forem de comprimentos diferentes, o vetor mais curto terá que ser estendido.
O número binário de 4 bits sem sinal “1000” é o decimal 8, enquanto o número de 4 bits com sinal “1000” é o decimal -8. O “1” na posição mais à esquerda do número com sinal indica que este é um número negativo. Portanto, os dois sinais de 4 bits são estendidos de forma diferente pelo compilador.
Esta é uma visualização de como a extensão de sinal cria os diferentes valores para o
Uns8
e Sig8
sinais:
Retirada
- Sinais do tipo com e sem sinal são vetores que podem ser usados em operações aritméticas
- Sinais do tipo assinado e não assinado irão transbordar silenciosamente
- A extensão de assinatura pode criar resultados diferentes para tipos assinados e não assinados
Ir para o próximo tutorial »
VHDL
- Assinado vs. Não assinado em VHDL
- Como usar um procedimento em um processo em VHDL
- Como usar uma função impura em VHDL
- Como usar uma função em VHDL
- Como usar um procedimento em VHDL
- Como usar constantes e mapa genérico em VHDL
- Como usar a instanciação do mapa de portas em VHDL
- Como instalar um simulador e editor VHDL gratuitamente
- Microcontrolador PIC18:o que é e como usá-lo
- O que é um designador de referência e como o usamos na montagem?