Aritmética com vetores em VDHL

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar

1 Uma breve introdução..

Em VHDL é possível fazer as operações aritméticas utilizando tipos INTEGER, REAL, FIXED e FLOAT. Os tipos INTEGER e REAL e seus operadores fazem parte do padrão VHDL e não requerem a inclusão de nenhuma biblioteca. O PACKAGE standard definido no IEEE Std 1076-2008 (Revision of IEEE Std 1076-2002) IEEE Standard VHDL Language Reference Manual, define os tipos e operadores mostrados em Standard.vhdl. Todos os operadores são implicitamente declarados e não podem ser alterados pelo usuário para os tipos do PACKAGE standard.

2 Um pouco de história..

Quando VHDL saiu em 1987, não havia previsão para tratamento lógico para valores com múltiplos valores. Os tipos de lógica estavam disponíveis apenas para bits ('0' e '1') e booleanos (TRUE e FALSE), os quais são apenas do tipo dois valores. Inicialmente, cada fornecedor de ferramenta de síntese criou seu próprio Pacote(Package) para o tratamento de múltiplos valores, o que levou a uma falta de portabilidade.

No padrão "IEEE Standard Multivalue Logic System for VHDL Model Interoperability (Stdlogic1164)" foi definido o valor resolvido para lógica com múltiplos valores do tipo std_logic. Assim o std_logic tornou-se o tipo de lógica padrão em projeto VHDL.

Uma segunda característica que faltava no VHDL original era uma maneira padrão de fazer operações aritméticas com tipos bit_vector e std_logic_vector. Novamente fornecedores de síntese desenvolvido seus próprios pacotes, alguns dos quais tornaram-se muito utilizado, mas em seguida, o IEEE criou "IEEE 1076.3 Standard VHDL Synthesis Packages". O qual definiu dois Pacotes: um para uso com tipos com base no bit numeric_bit e um para o uso com tipos com base na std_logic numeric_std.

FONTE: http://www.doulos.com/knowhow/vhdl_designers_guide/numeric_std/

3 Use apenas as bibliotecas da IEEE

Existem diversos forum sobre VHDL onde existem sugestões para uso das bibliotecas da Synopsis std_logic_arith e std_logic_unsigned no lugar das bibliotecas padrão do IEEE numeric_bit e numeric_std. Como a implementação da Synopsis não é padronizada, e diferentes fornecedores implementam o pacote de forma ligeiramente diferentes, o que pode resultar em problemas de portabilidade do código VHDL entre ferramentas de síntese de fabricantes diferentes. Dessa forma a melhor solução é adotar sempre que disponível as bibliotecas padronizadas pela IEEE.

Uma das principais diferenças é que a biblioteca numeric_std não dá uma interpretação numérica rígida para os tipos std_logic_vector, mas define os tipos relacionados unsigned e signed que podem ser interpretados numericamente ou bit a bit. Dessa forma as operações lógicas e aritméticas combinando operandos signed, unsigned e integer podem ser utilizados. Nas operações de soma o resultado será do tamanho do maior operando, sendo os bits de overflow (carry) e underflow (borrow) truncados. A std_logic_arith por outro lado assume que toda aritmética é do tipo unsigned'.

4 Bibliotecas IEEE

Para utilizar essas bibliotecas inclua no código:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_bit.all; 
use IEEE.numeric_std.all;

4.1 Pacote std_logic_1164.vhd

Este pacote prove a definição dos tipos de sinais std_ulogic, std_ulogic_vector, std_logic e std_logic_vector. O pacote também provê o overload dos seguintes operadores lógicos bit a bit e vetorizados: nand, or, nor, xor, xnor, not. Adicionalmente esse pacote define as funções de conversão de tipos e de detecção de borda.

Resumo das declarações dos tipos e funções
TYPE std_ulogic IS ( 'U',  -- Uninitialized
                      'X',  -- Forcing  Unknown
                      '0',  -- Forcing  0
                      '1',  -- Forcing  1
                      'Z',  -- High Impedance   
                      'W',  -- Weak     Unknown
                      'L',  -- Weak     0       
                      'H',  -- Weak     1       
                      '-'   -- Don't care
                    );

TYPE std_ulogic_vector IS ARRAY ( NATURAL RANGE <> ) OF std_ulogic;

SUBTYPE std_logic IS resolved std_ulogic;
TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic;

-------------------------------------------------------------------
-- conversion functions
-------------------------------------------------------------------
FUNCTION To_bit       ( s : std_ulogic;        xmap : BIT := '0') RETURN BIT;
FUNCTION To_bitvector ( s : std_logic_vector ; xmap : BIT := '0') RETURN BIT_VECTOR;
FUNCTION To_bitvector ( s : std_ulogic_vector; xmap : BIT := '0') RETURN BIT_VECTOR;
 
FUNCTION To_StdULogic       ( b : BIT               ) RETURN std_ulogic;
FUNCTION To_StdLogicVector  ( b : BIT_VECTOR        ) RETURN std_logic_vector;
FUNCTION To_StdLogicVector  ( s : std_ulogic_vector ) RETURN std_logic_vector;
FUNCTION To_StdULogicVector ( b : BIT_VECTOR        ) RETURN std_ulogic_vector;
FUNCTION To_StdULogicVector ( s : std_logic_vector  ) RETURN std_ulogic_vector;

-------------------------------------------------------------------    
-- edge detection
-------------------------------------------------------------------    
FUNCTION rising_edge  (SIGNAL s : std_ulogic) RETURN BOOLEAN;
FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;

4.2 Pacote numeric_std.vhd

Este pacote prove a definição dos tipos de sinais "unsigned" e "signed". O pacote também provê o dos seguintes operadores lógicos vetorizados: nand, or, nor, xor, xnor, not. Este pacote define as funções unárias "abs", "-", a função "resize", as operações aritméticas com dois operandos "+", "-", "*", "/", "rem", "mod", e as operações lógicas ">", ">=", "<", "<=", "=", "/=" para operandos numéricos. Adicionalmente o pacote define as funções de conversão TO_INTEGER e TO_UNSIGNED.

Resumo das declarações dos tipos e funções
--============================================================================
-- Numeric array type definitions
--============================================================================
 type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
 type SIGNED is array (NATURAL range <>) of STD_LOGIC;

--============================================================================
-- Operações Arithméticas com um argumento:
--===========================================================================
 function "abs" (ARG: SIGNED) return SIGNED; 
 function "-" (ARG: SIGNED) return SIGNED;   

--============================================================================
-- Operações Arithméticas com dois argumentos:
-- os dois argumentos podem ser do tipo UNSIGNED, SIGNED, INTEGER ou  NATURAL, 
-- o tipo do valor retornado depende dos operandos.
-- function "OPERACAO" (L, R: UNSIGNED) return UNSIGNED; 
-- function "OPERACAO" (L, R: SIGNED) return SIGNED;
-- function "OPERACAO" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
-- function "OPERACAO" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
-- function "OPERACAO" (L: INTEGER; R: SIGNED) return SIGNED;
-- function "OPERACAO" (L: SIGNED; R: INTEGER) return SIGNED;
--===========================================================================
 function "+" (L, R: UNSIGNED) return UNSIGNED; 
 function "-" (L, R: UNSIGNED) return UNSIGNED;
 function "*" (L, R: UNSIGNED) return UNSIGNED;;
 function "/" (L, R: UNSIGNED) return UNSIGNED;
 function "rem" (L, R: UNSIGNED) return UNSIGNED;
 function "mod" (L, R: UNSIGNED) return UNSIGNED;

--============================================================================
-- Operações de comparação:
-- os dois argumentos podem ser do tipo UNSIGNED, SIGNED, INTEGER ou  NATURAL,
-- o tamanho dos argumentos pode ser diferente
-- o tipo do valor retornado é sempre BOOLEAN.
-- function "COMPARACAO" (L, R: UNSIGNED) return BOOLEAN; 
-- function "COMPARACAO" (L, R: SIGNED) return BOOLEAN;
-- function "COMPARACAO" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
-- function "COMPARACAO" (L: INTEGER; R: SIGNED) return BOOLEAN;
-- function "COMPARACAO" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
-- function "COMPARACAO" (L: SIGNED; R: INTEGER) return BOOLEAN;;
--===========================================================================

 function  ">" (L, R: UNSIGNED) return BOOLEAN;
 function  "<" (L, R: UNSIGNED) return BOOLEAN;
 function "<=" (L, R: UNSIGNED) return BOOLEAN;
 function ">=" (L, R: UNSIGNED) return BOOLEAN;
 function  "=" (L, R: UNSIGNED) return BOOLEAN;
 function "/=" (L, R: UNSIGNED) return BOOLEAN;

--============================================================================
-- Shift and Rotate Functions
--============================================================================
  function SHIFT_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
  function SHIFT_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
  function ROTATE_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
  function ROTATE_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
  function "sll" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED;
  function "srl" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED;
  function "rol" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED;
  function "ror" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED;

--============================================================================
--   RESIZE Functions
--============================================================================
  function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;

--============================================================================
-- Conversion Functions
--============================================================================
  function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
  function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;

--============================================================================
-- Logical Operators
--============================================================================
  function "not" (L: UNSIGNED) return UNSIGNED;
  function "and" (L, R: UNSIGNED) return UNSIGNED;
  function "or" (L, R: UNSIGNED) return UNSIGNED;
  function "nand" (L, R: UNSIGNED) return UNSIGNED;
  function "nor" (L, R: UNSIGNED) return UNSIGNED;
  function "xor" (L, R: UNSIGNED) return UNSIGNED;
  function "xnor" (L, R: UNSIGNED) return UNSIGNED;

--============================================================================
-- Match Functions
--============================================================================
  function STD_MATCH (L, R: STD_ULOGIC) return BOOLEAN;

--============================================================================
-- Translation Functions
--============================================================================
  function TO_01 (S: UNSIGNED; XMAP: STD_LOGIC := '0') return UNSIGNED;

5 Bibliotecas não padronizadas

Evite utilizar em projetos as bibliotecas não padronizadas pelo IEEE. A seguir algumas bibliotecas que frequentemente são usadas em projetos VHDL mas que devem ser evitadas pois podem levar a falta de portabilidade do código em diferentes ferramentas de sintese e simulação.

5.1 Pacote std_logic_arith.vhd

Em projetos novos use sempre o pacote numeric_std da IEEE no lugar desse pacote. Para compatibilizar projetos antigos, o pacote std_logic_arith.vhd está disponível em http://www.vhdl.org. Esse pacote contem funções e tipos de dados que são semelhantes ao pacote o numeric_std, a seguir está a listagem dos tipos e funções definidas, com comentário indicando a função que o substitui.

5.1.1 Mentor Graphics x Synopsys

O PACKAGE std_logic_arith tem pequenas diferenças entre o fornecido pela Mentor Graphics e o de mesmo nome da Synopsys. Basicamente ambos pacotes definem o as operações para serem realizadas com os tipos SIGNED e UNSIGNED. Note no resumo abaixo que tanto o nome das funções com a quantidade estão definidos de forma diferente nestes dois pacotes.

Resumo das declarações dos tipos, operadores e funções - Mentor Graphics
   TYPE SIGNED   IS ARRAY (Natural RANGE <>) OF STD_LOGIC ;
   TYPE UNSIGNED IS ARRAY (Natural RANGE <>) OF STD_LOGIC ;
 
   FUNCTION to_integer 
   FUNCTION conv_integer 
   FUNCTION to_stdlogic 
   FUNCTION to_stdlogicvector
   FUNCTION to_stdulogicvector
   FUNCTION to_unsigned
   FUNCTION conv_unsigned
   FUNCTION to_signed
   FUNCTION conv_signed
   FUNCTION zero_extend
   FUNCTION sign_extend
   FUNCTION "+"
   FUNCTION "-"
   FUNCTION "*"
   FUNCTION "abs"
   FUNCTION "/"
   FUNCTION "MOD"
   FUNCTION "REM"
   FUNCTION "**"
   FUNCTION "sla" 
   FUNCTION "sra"
   FUNCTION "sll"
   FUNCTION "srl"
   FUNCTION "rol"
   FUNCTION "ror"
   FUNCTION eq 
   FUNCTION "="
   FUNCTION ne 
   FUNCTION "/="
   FUNCTION lt
   FUNCTION "<"
   FUNCTION gt
   FUNCTION ">" 
   FUNCTION le
   FUNCTION "<="
   FUNCTION ge
   FUNCTION ">="
   FUNCTION "and"
   FUNCTION "nand"
   FUNCTION "or" 
   FUNCTION "nor" 
   FUNCTION "xor"
   FUNCTION "not"
   FUNCTION "xnor"
Resumo das declarações dos tipos, operadores e funções - Synopsys
    type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
    type SIGNED is array (NATURAL range <>) of STD_LOGIC;

    function "+"
    function "-"
    function "ABS"
    function "*"
    function "<"
    function "<="
    function ">"
    function ">="
    function "="
    function "/="
    function SHL
    function CONV_INTEGER
    function CONV_UNSIGNED
    function CONV_SIGNED
    function CONV_STD_LOGIC_VECTOR
    function EXT     -- zero extend 
    function SXT     -- sign extend

5.1.2 Pacote std_logic_unsigned.vdh - Synopsys

Este pacote da Synopsys, complementa o pacote std_logic_arith. Esse pacote contem funções e tipos de dados que são semelhantes ao pacote o numeric_std. A função desse pacote é permitir realizar operações lógicas e aritméticas com argumentos do tipo std_logic_vector considerando eles como tipo unsigned.

Em projetos novos use sempre o pacote numeric_std da IEEE no lugar desse pacote, definindo os argumentos como unsigned.

5.1.3 Pacote std_logic_signed.vdh - Synopsys

Este pacote da Synopsys, complementa o pacote std_logic_arith. Esse pacote contem funções e tipos de dados que são semelhantes ao pacote o numeric_std. A função desse pacote é permitir realizar operações lógicas e aritméticas com argumentos do tipo std_logic_vector considerando eles como tipo signed.

Em projetos novos use sempre o pacote numeric_std da IEEE no lugar desse pacote, definindo os argumentos como signed.