Aritmética com vetores em VDHL

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

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.

SumaryOfNumeric std.gif

Numeric stdConvertions.gif

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

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'.

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;

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.

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;

Adicionalmente esse pacote define as funções de conversão de tipos e de detecção de borda.

-------------------------------------------------------------------
-- 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;

Pacote numeric_std.vhd

--============================================================================
-- 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;

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 evitas pois podem levar a falta de portabilidade do código em diferentes ferramentas de sintese e simulação.

Pacote std_logic_arith.vhd

Use no lugar desse pacote o numeric_std ou numeric_bit

   type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
   type SIGNED is array (NATURAL range <>) of STD_LOGIC;
   subtype SMALL_INT is INTEGER range 0 to 1;

   function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
   function "-"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
   function "+"(L: UNSIGNED) return UNSIGNED;
   function "-"(L: SIGNED) return SIGNED;
   function "ABS"(L: SIGNED) return SIGNED;
   function "*"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
   function "<"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
   function "<="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
   function ">"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
   function ">="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
   function "="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
   function "/="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
   function SHL(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED;
   function CONV_INTEGER(ARG: INTEGER) return INTEGER;
   function CONV_UNSIGNED(ARG: INTEGER; SIZE: INTEGER) return UNSIGNED;
   function CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER) return SIGNED;
   function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR;
   function EXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER) return STD_LOGIC_VECTOR;
   function SXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER) return STD_LOGIC_VECTOR;

</syntaxhighlight>