Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> VHDL

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


Ir para o próximo tutorial »

VHDL

  1. Assinado vs. Não assinado em VHDL
  2. Como usar um procedimento em um processo em VHDL
  3. Como usar uma função impura em VHDL
  4. Como usar uma função em VHDL
  5. Como usar um procedimento em VHDL
  6. Como usar constantes e mapa genérico em VHDL
  7. Como usar a instanciação do mapa de portas em VHDL
  8. Como instalar um simulador e editor VHDL gratuitamente
  9. Microcontrolador PIC18:o que é e como usá-lo
  10. O que é um designador de referência e como o usamos na montagem?