Aritmética com vetores em VDHL

De MediaWiki do Campus São José
Revisão de 20h58min de 10 de maio de 2016 por Moecke (discussão | contribs) (Um pouco de história..)
(dif) ← Edição anterior | Revisão atual (dif) | Versão posterior → (dif)
Ir para: navegação, pesquisa

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.

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

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;

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.

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.

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

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.

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.