Mudanças entre as edições de "DLP29006-Engtelecom(2020-2) - Prof. Marcos Moecke"
(→ATUAL) |
|||
Linha 224: | Linha 224: | ||
:* Objetivos: Copiar e colar o código no Quartus; diferença entre analise e síntese e compilação; observar o RTL (usar UNGROUP); simulação funcional e simulação temporal; observar os atrasos de propagação na simulação temporal. | :* Objetivos: Copiar e colar o código no Quartus; diferença entre analise e síntese e compilação; observar o RTL (usar UNGROUP); simulação funcional e simulação temporal; observar os atrasos de propagação na simulação temporal. | ||
− | |||
;Aula 6 (23 nov): | ;Aula 6 (23 nov): | ||
* Uso das bibliotecas no VHDL. | * Uso das bibliotecas no VHDL. | ||
Linha 328: | Linha 327: | ||
|background colour=#F5FFFA}} | |background colour=#F5FFFA}} | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 3 - Tipos de Dados e Operadores em VHDL=== | ||
+ | * 7 AULAS | ||
+ | |||
+ | {{collapse top | expand=true | Unidade 3 - Tipos de Dados e Operadores em VHDL}} | ||
+ | |||
+ | ====ATUAL==== | ||
+ | ;Aula 7 (24 nov): | ||
+ | *Comentários no código (duplo traço --) | ||
+ | -- Isso eh uma linha de comentario | ||
+ | y <= a * b ; --o sinal y recebe o resultado da multiplicacao a x b | ||
+ | *Representação de números e caracteres em VHDL. | ||
+ | :*Caracteres | ||
+ | caracter: 'A' 'x' '#' (com aspas simples) | ||
+ | string de caracteres: "IFSC" "teste" "teste123" | ||
+ | |||
+ | :*Números em geral | ||
+ | bit único: '0' '1' 'Z' (com aspas simples) | ||
+ | vetor de bits: "0110" "101001Z" (com aspas duplas) | ||
+ | vetor de 1 bit: "0" "1" (com aspas duplas) | ||
+ | inteiros: 5 1101 1102 (sem aspas) | ||
+ | |||
+ | :*Números binários: | ||
+ | 0 -> '0' | ||
+ | 7 -> "0111" ou b"0111" ou B"0111" | ||
+ | 1023 -> "001111111111" ou b"1111111111" ou B"1111111111" | ||
+ | |||
+ | :*Números octais: | ||
+ | 44 -> 5*8^1 + 4*8^0 -> O"54" ou o"54" | ||
+ | 1023 -> 1*8^3 + 7*8^2 + 7*8^1 + 7*8^0 -> o"1777" 8#1777# | ||
+ | |||
+ | :*Números Hexadecimais: | ||
+ | 1023 -> 3*16^2 + 15*16^1 + 15*16^0 = X"3FF" ou x"3FF" 16#3FF# | ||
+ | |||
+ | :*Números decimais: | ||
+ | 1023 -> 1023 ou 1_023 | ||
+ | 1000 -> 1000 ou 1_000 ou 1E3 | ||
+ | |||
+ | :*Números em outras bases (de 2 a 16) | ||
+ | 5#320# (3*5^2 + 2*5^1 + 0*5^0) -> 85 | ||
+ | 3#201#E4 (2*3^2+0*3^1+1*3^0)*3^4 -> 1539 | ||
+ | |||
+ | *Tipos de Dados em VHDL. | ||
+ | :*Objetos de VHDL: '''CONSTANT''', '''SIGNAL''', '''VARIABLE''', '''FILE'''. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | constant <constant_name> : <type> := <constant_value>; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A '''constant''' pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, PACKAGE_BODY, BLOCK, GENERATE, PROCESS, FUNCTION e PROCEDURE. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- Signal sem valor default | ||
+ | -- Para atribuir um valor a um signal use "<=" como operador. | ||
+ | |||
+ | signal <name> : <type>; | ||
+ | |||
+ | -- Signal com valor default | ||
+ | signal <name> : <type> := <default_value>; | ||
+ | |||
+ | -- Declarações comuns de signals | ||
+ | |||
+ | signal <name> : std_logic; | ||
+ | signal <name> : std_logic_vector(<msb_index> downto <lsb_index>); | ||
+ | signal <name> : integer; | ||
+ | signal <name> : integer range <low> to <high>; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | O '''signal''' pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, BLOCK, GENERATE. Os sinais não podem ser declarados no código sequencial (PROCESS, FUNCTION e PROCEDURE), mas podem ser usados. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- Variables devem ser declarada em process ou subprogramas. | ||
+ | -- Para atribuir um valor a um variable use ":=" como operador. | ||
+ | |||
+ | -- Variable sem valor default. | ||
+ | variable <name> : <type>; | ||
+ | |||
+ | -- Variable com valor default. | ||
+ | variable <name> : <type> := <default_value>; | ||
+ | |||
+ | -- Declarações comuns de variables | ||
+ | variable <name> : std_logic; | ||
+ | variable <name> : std_logic_vector(<msb_index> downto <lsb_index>); | ||
+ | variable <name> : integer; | ||
+ | variable <name> : integer range <low> to <high>; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | O '''variable''' (variável) só pode ser declarada e usada dentro do escopo no código sequencial (PROCESS, FUNCTION e PROCEDURE). | ||
+ | |||
+ | :*Palavra chave '''OTHERS''' para formação de agregados | ||
+ | Exemplos de declaração de CONSTANT, SIGNAL, VARIABLE, inicializando o valor usando o agregados | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | CONSTANT a: BIT_VECTOR(5 DOWNTO 0) := (OTHERS => '0'); -- "000000" | ||
+ | |||
+ | CONSTANT b: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', OTHERS => '1'); -- "01111111" | ||
+ | CONSTANT c: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', 6 DOWNTO 0 => '1'); -- "01111111" | ||
+ | CONSTANT d: BIT_VECTOR(7 DOWNTO 0) := "01111111"; | ||
+ | |||
+ | SIGNAL e: STD_LOGIC_VECTOR(7 DOWNTO 0); -- Not initialized | ||
+ | SIGNAL f: STD_LOGIC_VECTOR(1 TO 8) := (2|3|8 => '1', 4 => 'Z', OTHERS => '0' ); -- "011Z0001" | ||
+ | |||
+ | VARIABLE g: BIT_VECTOR(1 TO 16); -- Not initialized | ||
+ | VARIABLE h: BIT_VECTOR(1 TO 16) := (1 TO 8 => '1', OTHERS => '0'); -- "1111111100000000" | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | :: Ver pag. 31 a 35 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | :* Bibliotecas padrão IEEE ('''[[Std logic 1164.vhd]]''', '''[[Numeric std.vhd]]'''). | ||
+ | ::* '''ATENÇÃO!!! Não use as bibliotecas que não são padrão (''std_logic_arith, std_logic_unsigned, std_logic_signed''''') | ||
+ | ::* Ler e guardar a página sobre [[Aritmética com vetores em VDHL]] | ||
+ | |||
+ | * Classificação dos tipos de dados. | ||
+ | |||
+ | A biblioteca [[standard.vhd]] define os tipos BIT, BIT_VECTOR, BOOLEAN, INTEGER, NATURAL, POSITIVE, CHARACTER, STRING. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | package standard is | ||
+ | type boolean is (false,true); | ||
+ | type bit is ('0', '1'); | ||
+ | type severity_level is (note, warning, error, failure); | ||
+ | type integer is range -2147483647 to 2147483647; | ||
+ | type real is range -1.0E308 to 1.0E308; | ||
+ | type time is range -2147483648 to 2147483647 | ||
+ | units | ||
+ | fs; | ||
+ | ps = 1000 fs; | ||
+ | ns = 1000 ps; | ||
+ | us = 1000 ns; | ||
+ | ms = 1000 us; | ||
+ | sec = 1000 ms; | ||
+ | min = 60 sec; | ||
+ | hr = 60 min; | ||
+ | end units; | ||
+ | subtype natural is integer range 0 to integer'high; | ||
+ | subtype positive is integer range 1 to integer'high; | ||
+ | type string is array (positive range <>) of character; | ||
+ | type bit_vector is array (natural range <>) of bit; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A biblioteca [[Std logic 1164.vhd]] define os tipos STD_(U)LOGIG, STD_(U)LOGIG_VECTOR. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | PACKAGE std_logic_1164 IS | ||
+ | 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; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A biblioteca [[Std logic 1164.vhd]] ainda define algumas funções importantes como a '''rising_edge''' que determina se um sinal está na borda de subida (usado em sinais de clock). | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ------------------------------------------------------------------- | ||
+ | -- 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_StdULogic ( b : BIT ) RETURN std_ulogic; | ||
+ | FUNCTION To_StdLogicVector ( b : BIT_VECTOR ) RETURN std_logic_vector; | ||
+ | |||
+ | ------------------------------------------------------------------- | ||
+ | -- edge detection | ||
+ | ------------------------------------------------------------------- | ||
+ | FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN; | ||
+ | FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN; | ||
+ | |||
+ | ------------------------------------------------------------------- | ||
+ | -- edge detection | ||
+ | ------------------------------------------------------------------- | ||
+ | FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS | ||
+ | -- altera built_in builtin_rising_edge | ||
+ | BEGIN | ||
+ | RETURN (s'EVENT AND (To_X01(s) = '1') AND | ||
+ | (To_X01(s'LAST_VALUE) = '0')); | ||
+ | END; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | A biblioteca [[Numeric std.vhd]] define os tipos UNSIGNED e SIGNED. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | package NUMERIC_STD is | ||
+ | type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; | ||
+ | type SIGNED is array (NATURAL range <>) of STD_LOGIC; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A biblioteca [[Numeric std.vhd]] ainda define os operadores (abs, "+", "-", "*", "\", rem, mod, sll, slr, ror, rol), comparações ("=", '/=', ">", ">=", "<", "<=") e operadores lógicos (not, and, nand, or, nor, xor, xnor) para os tipos SIGNED e UNSIGNED. Além disso também define algumas funções muito utilizadas como: | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --============================================================================ | ||
+ | -- RESIZE Functions | ||
+ | --============================================================================ | ||
+ | function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED; | ||
+ | function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED; | ||
+ | |||
+ | --============================================================================ | ||
+ | -- Conversion Functions | ||
+ | --============================================================================ | ||
+ | function TO_INTEGER (ARG: UNSIGNED) return NATURAL; | ||
+ | function TO_INTEGER (ARG: SIGNED) return INTEGER; | ||
+ | function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED; | ||
+ | function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* Resumo dos Tipos predefinidos. | ||
+ | {| class="wikitable sortable" border="1" cellpadding="3" cellspacing="0" style="text-align:left; font-size:100%" bgcolor="#efefef" | ||
+ | ! scope="col" width=15% align="left"| Tipo de Dado | ||
+ | ! scope="col" width=10% align="left"| Package | ||
+ | ! scope="col" width=7% align="left"| Library | ||
+ | ! scope="col" width=50% align="left"| Valores | ||
+ | ! scope="col" width=15% align="left"| Observações | ||
+ | |- | ||
+ | | BOOLEAN || standard || std || TRUE e FALSE || sintetizável | ||
+ | |- | ||
+ | | BIT || standard || std || valores '0', '1' || sintetizável | ||
+ | |- | ||
+ | | INTEGER || standard || std || números inteiros de 32 bits [de -2^31 até + (2^31 - 1)] || sintetizável | ||
+ | |- | ||
+ | | NATURAL || standard || std || números inteiros não negativos [de 0 até + (2^31 - 1)] || sintetizável | ||
+ | |- | ||
+ | | POSITIVE || standard || std || números inteiros positivos [de 1 até + (2^31 - 1)] || sintetizável | ||
+ | |- | ||
+ | | BOOLEAN_VECTOR || standard (2008) || std || vetor de BOOLEAN || sintetizável | ||
+ | |- | ||
+ | | BIT_VECTOR || standard || std || vetor de BIT || sintetizável | ||
+ | |- | ||
+ | | INTEGER_VECTOR || standard || std || vetor de INTEGER || sintetizável | ||
+ | |- | ||
+ | | REAL || standard || std || números reais [de -1.0E-38 até + 1.0E38] || simulação | ||
+ | |- | ||
+ | | CHARACTER || standard || std || caracteres ASCII || | ||
+ | |- | ||
+ | | STRING || standard || std || vetor de CHARACTER || | ||
+ | |- | ||
+ | | STD_LOGIC || std_logic_1164 || ieee || valores 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-' || sintetizável | ||
+ | |- | ||
+ | | STD_LOGIC_VECTOR || std_logic_1164 || ieee || vetor de STD_LOGIC || sintetizável | ||
+ | |- | ||
+ | | SIGNED || numeric_std || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas com sinal|| sintetizável | ||
+ | |- | ||
+ | | UNSIGNED || numeric_std || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas || sintetizável | ||
+ | |- | ||
+ | | SIGNED || numeric_bit || ieee || BIT_VECTOR que aceitam operações aritméticas com sinal || sintetizável | ||
+ | |- | ||
+ | | UNSIGNED || numeric_bit || ieee || BIT_VECTOR que aceitam operações aritméticas || sintetizável | ||
+ | |- | ||
+ | | SIGNED || std_logic_arith || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas com sinal || sintetizável (não é padrão) | ||
+ | |- | ||
+ | | UNSIGNED || std_logic_arith || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas || sintetizável (não é padrão) | ||
+ | |- | ||
+ | | UFIXED || fixed_pkg + (2008) || ieee || números de ponto fixo sem sinal|| sintetizável | ||
+ | |- | ||
+ | | SFIXED || fixed_pkg + (2008) || ieee || números de ponto fixo com sinal|| sintetizável | ||
+ | |- | ||
+ | | FLOAT || float_pkg + (2008) || ieee || Números de ponto flutuante || sintetizável | ||
+ | |} | ||
+ | |||
+ | :* Tipos de dados predefinidos: FIXED e FLOAT (apenas conhecer) | ||
+ | * '''Desafio''' - Fazer um circuito que detecte se existe alguma vaga vazia em um lote de 5 vagas. Cada entrada x(n) está alta '1' se a vaga está vazia. A saída y estará alta '1' sempre que houver uma ou mais vagas vazias. | ||
+ | *Faça a simulação do circuito para ver se está funcionando, | ||
+ | {{fig|3.1| Simulação de contador de vagas | vagas5.png | 800 px |}} | ||
+ | :: Ver função resize | ||
+ | :: Ver pag. 73 a 78 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | <!-- | ||
+ | ;Aula 7 (26 nov): | ||
+ | |||
+ | :* Exemplo 3.1 Buffer Tri-state | ||
+ | *Ver como funciona em [http://bibl.ica.jku.at/dc/build/html/basiccircuits/basiccircuits.html#figure-1] | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | |||
+ | entity tri_state is | ||
+ | generic (N: NATURAL := 1); | ||
+ | port | ||
+ | ( | ||
+ | input : in std_logic_vector(N-1 downto 0); | ||
+ | ena : in std_logic; | ||
+ | output : out std_logic_vector(N-1 downto 0); | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture tri_state of tri_state is | ||
+ | begin | ||
+ | output <= input when ena = '1' else "Z"; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::* Corrija os erros do código e verifique o modelo RTL obtido. | ||
+ | ::* Em seguida modifique as portas '''input''' e '''output''' para o tipo '''std_logic'''. | ||
+ | ::* Analise se seria possível modificar as portas para o tipo '''bit'''. | ||
+ | :: '''Importante''': O terceiro estado 'Z' só pode ser usado em saídas, e a sua realização nos FPGAs só ocorre nos nós de I/O. | ||
+ | |||
+ | :* Exemplo 3.2 Circuito com Saida "don't care" | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | |||
+ | entity Ex3_2 is | ||
+ | port | ||
+ | ( | ||
+ | x : in STD_LOGIC_VECTOR(1 downto 0); | ||
+ | y : out STD_LOGIC_VECTOR(1 downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture un3 of Ex3_2 is | ||
+ | begin | ||
+ | y <= "00" when x = "00" else | ||
+ | "01" when x = "10" else | ||
+ | "10" when x = "01" else | ||
+ | "--"; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Inspirado na descrição VHDL acima, tente resolver o '''Desafio ''' - Fazer um circuito que detecte se existe alguma vaga vazia em um lote de 5 vagas. Cada entrada x(n) está alta '1' se a vaga está vazia. A saída y estará alta '1' sempre que houver uma ou mais vagas vazias. | ||
+ | :'''Importante''': O ''don't care'' não funciona como se espera para uma entrada, por isso, use ''don't care'' apenas para saídas. | ||
+ | x = "1----" -- não funciona em VHDL | ||
+ | *Se quiser mesmo usar ''don't care'' em entradas use a função '''std_match''' do pacote '''numeric_std''' | ||
+ | std_match(x, "1----") -- funciona em VHDL | ||
+ | |||
+ | ;Aula 11 (11 mar): | ||
+ | :* Tipos de dados: SIGNED e UNSIGNED | ||
+ | |||
+ | :* Exemplo 3.3 Multiplicador de 4x4 bits (UN)SIGNED e INTEGER | ||
+ | |||
+ | {{collapse top | Código Multiplicador}} | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --LIBRARY ieee; | ||
+ | --USE ieee.numeric_std.all; | ||
+ | |||
+ | ENTITY multiplicador4x4 IS | ||
+ | |||
+ | -- multiplicador usando INTEGER (positivos) | ||
+ | -- PORT (a, b: IN INTEGER RANGE 0 TO 15; -- min(a) = 0; max(a) = 15 -> 4 bits | ||
+ | -- y: OUT INTEGER RANGE 0 TO 225); -- min(a*b) = 0, max(a*b) = 225 -> 8 bits | ||
+ | |||
+ | -- multiplicador usando INTEGER (positivos e negativos) | ||
+ | -- PORT (a, b: IN INTEGER RANGE -8 TO 7; -- min(a) = -8; max(a) = 7 -> 4 bits | ||
+ | -- y: OUT INTEGER RANGE -56 TO 64); -- min(a*b) = -56, max(a*b) = 64 -> 8 bits | ||
+ | |||
+ | -- multiplicador usando UNSIGNED | ||
+ | -- PORT (a, b: IN UNSIGNED(3 DOWNTO 0); -- min(a) = 0; max(a) = 15 <- 4 bits | ||
+ | -- y: OUT UNSIGNED(7 DOWNTO 0)); -- min(a*b) = 0, max(a*b) = 225 -> 8 bits | ||
+ | |||
+ | -- multiplicador usando SIGNED | ||
+ | -- PORT (a, b: IN SIGNED(3 DOWNTO 0); -- min(a) = -8; max(a) = 7 <- 4 bits | ||
+ | -- y: OUT SIGNED(7 DOWNTO 0)); -- min(a*b) = -56, max(a*b) = 64 -> 8 bits | ||
+ | |||
+ | |||
+ | -- multiplicador usando STD_LOGIC_VECTOR | ||
+ | -- PORT (a, b: IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- min(a) = 0; max(a) = 15 <- 4 bits | ||
+ | -- y: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); -- min(a*b) = 0, max(a*b) = 225 -> 8 bits | ||
+ | |||
+ | -- multiplicador usando STD_LOGIC_VECTOR | ||
+ | -- PORT (a, b: STD_LOGIC_VECTOR(3 DOWNTO 0); -- min(a) = -8; max(a) = 7 <- 4 bits | ||
+ | -- y: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); -- min(a*b) = -56, max(a*b) = 64 -> 8 bits | ||
+ | |||
+ | |||
+ | END ENTITY; | ||
+ | |||
+ | ARCHITECTURE v1 OF multiplicador4x4 IS | ||
+ | BEGIN | ||
+ | y <= a * b; | ||
+ | END ARCHITECTURE; | ||
+ | </syntaxhighlight> | ||
+ | *Observar o número de elementos lógicos, bits usados para representar as entradas e saídas. | ||
+ | *Observar o código RTL obtido. | ||
+ | *Realizar a simulação com entradas UNSIGNED e INTEGER na faixa de valores de 0 até 15, e analisar se o valor da saída está correto. | ||
+ | *Realizar a simulação com entradas SIGNED e INTEGER na faixa de valores de -8 até 7, e analisar se o valor da saída está correto. | ||
+ | *Realizar a simulação com entradas STD_LOGIC_VECTOR na faixa de valores de 0 até 15, e analisar se o valor da saída está correto. Neste caso será necessário realizar uma conversão de STD_LOGIC_VECTOR para UNSIGNED antes de efetuar a operação de "*", e após a operação é necessário fazer a operação inversa UNSIGNED para STD_LOGIC_VECTOR | ||
+ | *Realizar a simulação com entradas STD_LOGIC_VECTOR na faixa de valores de -8 até 7, e analisar se o valor da saída está correto. Neste caso será necessário realizar uma conversão de STD_LOGIC_VECTOR para SIGNED antes de efetuar a operação de "*", e após a operação é necessário fazer a operação inversa SIGNED para STD_LOGIC_VECTOR | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | :: Ver pag. 39 a 54 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;Aula 12 (13 mar): | ||
+ | |||
+ | *Operadores em VHDL. | ||
+ | :* Operadores predefinidos: Atribuição, Lógicos, Aritméticos, Comparação, Deslocamento, Concatenação, "Matching". | ||
+ | :* Exemplo conversor de binário para BCD de dois dígitos decimais (00 a 99). Para ilustrar são utilizadas os operadores DIVISOR e REMAINDER. Note a quantidade de elementos lógicos utilizados. É possível reduzir essa quantidade, aproveitando resultados intermediários e evitando a realização de uma nova divisão pelo uso do operador REM. Faça uma segunda implementação que reduza significativamente o número de elementos lógicos. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | use ieee.numeric_std.all; | ||
+ | |||
+ | entity bin2bcd is | ||
+ | port | ||
+ | ( | ||
+ | |||
+ | C : in std_logic_vector (6 downto 0); | ||
+ | sd, su : out std_logic_vector (3 downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ifsc_v1 of bin2bcd is | ||
+ | signal C_uns : unsigned (6 downto 0); | ||
+ | signal sd_uns, su_uns : unsigned (6 downto 0); | ||
+ | begin | ||
+ | sd <= std_logic_vector(resize(sd_uns, 4)); | ||
+ | su <= std_logic_vector(resize(su_uns, 4)); | ||
+ | sd_uns <= C_uns/10; | ||
+ | su_uns <= C_uns rem 10; | ||
+ | c_uns <= unsigned(c); | ||
+ | end architecture; | ||
+ | |||
+ | architecture ifsc_v2 of bin2bcd is | ||
+ | |||
+ | begin | ||
+ | -- Implemente o circuito usando a definição de REM que é: x REM y = x - (x/y)*y | ||
+ | end architecture; | ||
+ | |||
+ | configuration bin2bcd_cfg of bin2bcd is | ||
+ | --A instrução '''configuration''' associa a '''entity''' bin2bcd a '''architecture'''. | ||
+ | for ifsc_v1 end for; | ||
+ | --Para associar a '''entity''' bin2bcd a '''architecture''' ifsc_v2 comente a linha acima e descomente a linha abaixo. | ||
+ | -- for ifsc_v2 end for; | ||
+ | end configuration; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {{fig|3.2| RTL do conversor de Binário para BCD com 2 digitos | bin2bcdDU_RTL.png | 600 px |}} | ||
+ | |||
+ | {{fig|3.3| Simulação do conversor de Binário para BCD com 2 digitos | bin2bcdDU_modelsim.png | 1000 px |}} | ||
+ | |||
+ | ====INICIO DAS AULAS REMOTAS SÍNCRONAS==== | ||
+ | |||
+ | ;Aula 13 (24 mar): | ||
+ | Atributos em VHDL. | ||
+ | * Atributos predefinidos: | ||
+ | ::*tipo escalar e enumerados; tipo array; de sinal; | ||
+ | * Atributos de síntese: | ||
+ | Em VHDL existem diversos atributos de sintese que controlam a forma como o processo de "Analysis & Synthesis" é realizado pelo Quartus II. Uma listagem completa pode ser encontrada em: | ||
+ | *[https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir.htm VHDL Synthesis Attributes and Directives] - Quartus Prime Pro Edition Help version 18.1 | ||
+ | |||
+ | :* '''ATTRIBUTE enum_encoding''' [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_enum_encoding.htm] | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | type fruit is (apple, orange, pear, mango); | ||
+ | attribute enum_encoding : string; | ||
+ | attribute enum_encoding of fruit : type is "11 01 10 00"; | ||
+ | </syntaxhighlight> | ||
+ | :* '''ATTRIBUTE chip_pin''' [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_chip.htm] | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity foo is | ||
+ | port (sel : in std_logic; | ||
+ | data : in std_logic_vector(3 downto 0); | ||
+ | o : out std_logic); | ||
+ | end foo; | ||
+ | architecture rtl of foo is | ||
+ | |||
+ | attribute chip_pin : string; | ||
+ | attribute chip_pin of sel : signal is "C4"; | ||
+ | attribute chip_pin of data : signal is "D1, D2, D3, D4"; | ||
+ | begin | ||
+ | -- Specify additional code | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | <i> | ||
+ | O uso desse atributo sobrepõe a atribuição dos pinos através da IDE do Quartus II, e por isso não é recomendável. | ||
+ | |||
+ | O atributo de síntese chip_pin pode ser usado apenas em portas da entidade "top-level" do projeto. . | ||
+ | </i> | ||
+ | |||
+ | :* '''ATTRIBUTE keep''' [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_keep.htm] | ||
+ | O atributo de síntese KEEP, sinaliza ao processo de "Analysis & Synthesis" para manter intacto um determinado signal ou componente. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | signal a,b,c : std_logic; | ||
+ | attribute keep: boolean; | ||
+ | attribute keep of a,b,c: signal is true; | ||
+ | </syntaxhighlight> | ||
+ | :::* Exemplo 4.4: Delay line (Síntese e Simulação temporal sem o com o atributo keep) | ||
+ | :::* Exemplo 5.8 Gerador de Pulsos estreitos | ||
+ | ::* '''ATTRIBUTE preserve''' [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_preserve.htm], [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#logicops/logicops/def_preserve_fanout_free_node.htm]. | ||
+ | |||
+ | ;Aula 14 (26 mar): | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | signal a,b,c : std_logic; | ||
+ | attribute preserve: boolean; | ||
+ | attribute preserve of a,b,c: signal is true; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* '''ATTRIBUTE noprune'''[https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_noprune.htm]. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | signal reg1: std_logic; | ||
+ | attribute noprune: boolean; | ||
+ | attribute noprune of reg1: signal is true; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exemplo 4.5: Registros redundantes}} | ||
+ | Síntese sem e com os atributos keep, preserve e noprune | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ENTITY redundant_registers IS | ||
+ | PORT ( | ||
+ | clk, x: IN BIT; | ||
+ | y: OUT BIT); | ||
+ | END ENTITY; | ||
+ | |||
+ | ARCHITECTURE arch OF redundant_registers IS | ||
+ | SIGNAL a, b, c: BIT; | ||
+ | -- NORMAL -- 1 LE | ||
+ | --ATTRIBUTE preserve: BOOLEAN; | ||
+ | --ATTRIBUTE preserve OF a, b, c: SIGNAL IS TRUE; -- 2 LE | ||
+ | --ATTRIBUTE noprune: BOOLEAN; | ||
+ | --ATTRIBUTE noprune OF a, b, c: SIGNAL IS TRUE; --3 LE | ||
+ | --ATTRIBUTE keep: BOOLEAN; | ||
+ | --ATTRIBUTE keep of a,b,c: SIGNAL IS TRUE; | ||
+ | BEGIN | ||
+ | PROCESS (clk) | ||
+ | BEGIN | ||
+ | IF (clk'EVENT AND clk='1') THEN | ||
+ | a <= x; | ||
+ | b <= x; | ||
+ | c <= x; | ||
+ | END IF; | ||
+ | END PROCESS; | ||
+ | y <= a AND b; | ||
+ | END ARCHITECTURE; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Após a compilação do código acima, observe o número de elementos lógicos obtidos, observe o '''Technology Map''' dos circuitos gerados e verifique a localização dos FFs no '''Chip Planner'''. | ||
+ | {{fig|3.4| Technology Map do circuito compilado sem Attribute | Ex4_5_NoAttribute.png | 400 px |}} | ||
+ | |||
+ | {{fig|3.5| Technology Map do Circuito com Attribute Preserve (or Keep) | Ex4_5_PreserveAttribute.png | 400 px |}} | ||
+ | |||
+ | {{fig|3.6| Technology Map do Circuito com Attribute Noprune | Ex4_5_NopruneAttribute.png | 400 px |}} | ||
+ | |||
+ | :: Ver pag. 91 a 111 de <ref name="PEDRONI2010b"/> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | :* Atributos definidos pelo usuário; | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | attribute attribute_name: attribute_type; | ||
+ | attribute attribute_name of entity_tag [signature]: entity_class is value; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | :* Tipos definidos pelo usuário: | ||
+ | ::* Escalares (Inteiros e Enumerados) | ||
+ | ::* Tipos de Array 1D x 1D, 2D , 1D x 1D x 1D, 3D. Ver : [[Array em VHDL]] | ||
+ | |||
+ | ;Aula 16 (31 mar): | ||
+ | {{collapse top| bg=lightyellow | Exemplo 3.5: Array de Integers 1D x 1D}} | ||
+ | O código abaixo cria um '''array''' de inteiros e utiliza as entradas "row" para fazer a leitura dos dados em uma tabela declarada como '''constant'''. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity array_1Dx1D_integer is | ||
+ | port ( | ||
+ | row : in integer range 1 to 3; | ||
+ | slice : out integer range 0 to 15 | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture teste of array_1Dx1D_integer is | ||
+ | type a1Dx1D_integer is array (1 to 3) of integer range 0 to 15; | ||
+ | constant table : a1Dx1D_integer := (15, 5, 7); | ||
+ | begin | ||
+ | slice <= table(row); | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | Responda as seguintes perguntas: | ||
+ | :1) Faça um desenho que represente o ARRAY declarado acima. | ||
+ | :2) Quantos bits são necessários para representar esse ARRAY? | ||
+ | :3) Qual o valor na saída quando a entrada row = 2? | ||
+ | :4) Quantos elementos lógicos são necessários para fazer a síntese deste circuito? | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exemplo 3.6: Array de bits 1D x 1D }} | ||
+ | O código abaixo cria um '''array''' de bits e utiliza as entradas "row" e "column" para fazer a leitura dos dados em uma tabela declarada como '''constant'''. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | |||
+ | entity array_1Dx1D_bit is | ||
+ | port ( | ||
+ | row : in integer range 1 to 3; | ||
+ | column : in integer range 0 to 4; --3 bits | ||
+ | slice1 : out bit; | ||
+ | slice2 : out BIT_VECTOR(1 to 2); | ||
+ | slice3 : out BIT_VECTOR(1 to 4); | ||
+ | slice4 : out BIT_VECTOR(1 to 3) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture teste of array_1Dx1D_bit is | ||
+ | type a1Dx1D_bit is array (1 to 3) of BIT_VECTOR(1 to 4); | ||
+ | constant table : a1Dx1D_bit := | ||
+ | (('1', '1', '1', '1'), --15 | ||
+ | ('0', '1', '0', '1'), -- 5 | ||
+ | ('0', '1', '1', '1')); -- 7 | ||
+ | begin | ||
+ | --slice1 <= table(row)(column); | ||
+ | --slice2 <= table(row)(1 to 2); | ||
+ | --slice3 <= table(row)(1 to 4); | ||
+ | --slice4 <= table(1 TO 3)(column); | ||
+ | --slice4 <= table(1)(column) & table(2)(column) & table(3)(column); | ||
+ | |||
+ | --gen : for i in 1 to 3 generate | ||
+ | -- slice4(i) <= table(i)(column); | ||
+ | --end generate; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | Responda as seguintes perguntas: | ||
+ | :1) Faça um desenho que represente o ARRAY declarado acima. | ||
+ | :2) Quantos bits são necessários para representar esse ARRAY? | ||
+ | :3) Descomente uma a uma as linhas na architecture. Verifique quais são aceitas pelo compilador? As 3 últimas formam um bloco único | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exemplo 3.7: Array de bits 2D }} | ||
+ | O código abaixo cria um '''array''' de bits e utiliza as entradas "row" e "column" para fazer a leitura dos dados em uma tabela declarada como '''constant'''. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity array_2D_bits is | ||
+ | port ( | ||
+ | row : in integer range 0 to 3; | ||
+ | column : in integer range 0 to 4; --3 bits | ||
+ | slice1 : out bit; | ||
+ | slice2 : out BIT_VECTOR(1 to 2); | ||
+ | slice3 : out BIT_VECTOR(1 to 4); | ||
+ | slice4 : out BIT_VECTOR(1 to 3) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture teste of array_2D_bits is | ||
+ | type a2D_bits is array (1 to 3, 1 to 4) of bit; | ||
+ | constant table : a2D_bits := (('0', '0', '0', '1'), | ||
+ | ('1', '0', '0', '1'), ('1', '1', '0', '1') | ||
+ | ); | ||
+ | begin | ||
+ | --slice1 <= table(row, column); | ||
+ | --slice2 <= table(row, 1 TO 2); | ||
+ | --slice3 <= table(row, 1 TO 4); | ||
+ | --slice4 <= table(1 TO 3, column); | ||
+ | --slice4 <= table(1, column) & table(2, column) & tabl | ||
+ | --gen : for i in 1 to 3 generate | ||
+ | -- slice4(i) <= table(i, column); | ||
+ | --end generate; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | Responda as seguintes perguntas: | ||
+ | :1) Faça um desenho que represente o ARRAY declarado acima. | ||
+ | :2) Quantos bits são necessários para representar esse ARRAY? | ||
+ | :3) Descomente uma a uma as linhas na architecture. Verifique quais são aceitas pelo compilador? As 3 últimas formam um bloco único | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | *A retirada de fatias (SLICES) dos ARRAYs só pode ser feita se o array foi definido com um vetor de vetores. Mesmo assim é necessário respeitar a ordem dos índices do BIT_VECTOR. No caso abaixo é ascendente (TO), e dentro dos limites (1 to 4). | ||
+ | |||
+ | type a1Dx1D_bit is array (1 to 3) of BIT_VECTOR(1 to 4); | ||
+ | |||
+ | * A retirada de fatias (SLICES) dos ARRAYs por coluna ou em ARRAY 2D ou 3D pode ser feita usando a retirada de elemento a elemento e concatenando-os ou atribuindo-os diretamente ao vetor de saída. | ||
+ | |||
+ | type a2D_bits is array (1 to 3, 1 to 4) of bit; | ||
+ | type a3D_bits is array (1 to 3, 1 to 4, 1 to 2) of bit; | ||
+ | |||
+ | :Concatenando por linha (ROW) ou coluna (COLUMN). | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | slice3 <= table(row, 1) & table(row, 2) & & table(row, 3) & & table(row, 4); | ||
+ | slice4 <= table(1, column) & table(2, column) & table(3, column); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :Amostrando elemento a elemento por linha (ROW) ou coluna (COLUMN) | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | gen1 : for j in 1 to 4 generate | ||
+ | slice3(j) <= table(row, j); | ||
+ | end generate; | ||
+ | gen2 : for i in 1 to 3 generate | ||
+ | slice4(i) <= table(i, column); | ||
+ | end generate; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | ;Aula 17 (1 abr): | ||
+ | |||
+ | * A implementação de circuitos aritméticos com operadores deve seguir as seguintes recomendações: | ||
+ | :* Para o uso dos operadores o mais adequado é utilizar o padrão industrial '''STD_LOGIC_VECTOR'''. Internamente os valores das portas devem ser convertidos ou para valores '''INTEGER''' ou para '''UNSIGNED'''/'''SIGNED'''. para tal é necessário utilizar o pacote '''numeric_std''' da biblioteca '''ieee'''. | ||
+ | {{fig|3.7| Conversões entre tipos Integer, Unsigned, Signed, Std_logic_vector | Numeric_stdConvertions.gif | 600 px | [[Aritmética com vetores em VDHL]]}} | ||
+ | |||
+ | :* a conversão de um objeto (vetor)'''a_SLV''' do tipo STD_LOGIC_VECTOR para um objeto (vetor)'''a_UNS (a_SIG)''' do tipo UNSIGNED (SIGNED) é feita pela conversão de tipo '''UNSIGNED''' | ||
+ | a_UNS <= unsigned(a_SLV); | ||
+ | a_SIG <= signed(a_SLV); | ||
+ | |||
+ | :* a conversão de um objeto (vetor) '''a_UNS (a_SIG)''' do tipo UNSIGNED (SIGNED) para um objeto (escalar)'''a_INT''' do tipo INTEGER é feita pela chamada da função '''TO_INTEGER''' | ||
+ | a_INT <= to_integer(a_UNS)); | ||
+ | a_INT <= to_integer(a_SIG)); | ||
+ | |||
+ | :* a conversão de um objeto (vetor) '''a_UNS (a_SIG)''' do tipo UNSIGNED (SIGNED) para um objeto (vetor) '''a_SLV''' do tipo STD_LOGIC_VECTOR é feita pela conversão de tipo '''STD_LOGIC_VECTOR''' | ||
+ | a_SLV <= std_logic_vector(a_UNS); | ||
+ | a_SLV <= std_logic_vector(a_SIG); | ||
+ | |||
+ | :* a conversão de um objeto (escalar) '''a_INT''' do tipo para um objeto (vetor) '''a_UNS (a_SIG)''' do tipo UNSIGNED (SIGNED) é feita pela chamada da função '''TO_UNSIGNED''' ('''TO_SIGNED'''). Essa função tem um segundo parâmetro que indica o número de bits '''NBITS''' desse um objeto (vetor). | ||
+ | a_UNS <= to_unsigned(a_INT,NBITS)); | ||
+ | a_SIG <= to_signed(a_INT, NBITS)); | ||
+ | |||
+ | |||
+ | :* Também é fundamental considerar a faixa de valores coberta por <math> N </math> bits. Para tipos '''UNSIGNED''' a faixa é de <math> 0 </math> até <math> 2^{N}-1 </math>, enquanto que para '''SIGNED''' a faixa é de <math> -2^{N-1} </math> até <math> 2^{N-1}-1 </math>. | ||
+ | *Assim com 3 bits é possível representar valores entre -4 até 3 com um tipo SIGNED e 0 até 7 com um tipo UNSIGNED. | ||
+ | :* Para uso adequado dos operadores também é necessário considerar o tamanho (número de bits) requerido para o resultado em função do tamanho dos operandos. A declaração dessas funções "+", "-", "*" e "/" no PACKAGE [[Numeric std.vhd]] mostra o tamanho a ser obtido no resultado. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | function "+" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). | ||
+ | -- Result: Adds two UNSIGNED vectors that may be of different lengths. | ||
+ | |||
+ | function "-" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). | ||
+ | -- Result: Subtracts two UNSIGNED vectors that may be of different lengths. | ||
+ | |||
+ | function "*" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0). | ||
+ | -- Result: Performs the multiplication operation on two UNSIGNED vectors | ||
+ | -- that may possibly be of different lengths. | ||
+ | |||
+ | function "/" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) | ||
+ | -- Result: Divides an UNSIGNED vector, L, by another UNSIGNED vector, R. | ||
+ | -- NOTE: If second argument is zero for "/" operator, a severity level of ERROR is issued. | ||
+ | |||
+ | function "rem" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) | ||
+ | -- Result: Computes "L rem R" where L and R are UNSIGNED vectors. | ||
+ | |||
+ | function "mod" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) | ||
+ | -- Result: Computes "L mod R" where L and R are UNSIGNED vectors. | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | *Portanto podemos concluir que: | ||
+ | :* Para operações de "+" ou "-": O tamanho do resultado é igual ao tamanho do maior operando. | ||
+ | ::Exemplo: r[7..0] = a[7..0] + b[4..0]; a -> 8 bits; b -> 5 bits então r -> 8 bits. | ||
+ | :* Para a operações "*": O tamanho do resultado é igual a soma do tamanho dos dois operandos. | ||
+ | ::Exemplo: r[12..0] = a[7..0] * b[4..0]; a -> 8 bits; b -> 5 bits então r -> 8+5 = 13 bits. | ||
+ | :* Para "/": O tamanho do resultado é igual ao tamanho do numerador. | ||
+ | ::Exemplo: r[5..0] = a[5..0] / b[8..0]; a -> 6 bits; b -> 9 bits então r -> 6 bits. | ||
+ | * No caso da operações de "*" e "/" não ocorre ''overflow'', no entanto no caso da "+" e "-", o ''overflow/underflow'' pode ocorrer e precisa ser tratado. Isso pode ser feito acrescentando um bit adicional a saída para conter o ''overflow'' ou então sinalizar a sua ocorrência com um bit na saída do circuito. Note que no caso em que ocorrem sucessivas somas, é impraticável ficar aumentando o número de bits para evitar o ''overflow'', de modo que a sinalização do ''overflow'' ou uso de escalas, ou representação em ponto fixo ou ponto flutuante podem ser as soluções a serem adotadas. | ||
+ | * No caso das operações de "+" e "-" também pode ser necessário tratar os sinais de ''carry in'' e ''carry out'', que permitem ampliar o tamanho de um somador realizando a sua conexão em cascata, ao mesmo tempo que tratam o ''overflow''. | ||
+ | |||
+ | :* Exercício: Multiplicador/Divisor/Somador/Subtrator com sinal e sem sinal (entradas do tipo STD_LOGIC VECTOR) | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exercício: Multiplicador/Divisor/Somador/Subtrator }} | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | |||
+ | entity operadores is | ||
+ | port ( | ||
+ | a : in std_logic_vector(5 downto 0); -- 6 bits | ||
+ | b : in std_logic_vector(2 downto 0); -- 3 bits | ||
+ | sum : out std_logic_vector(? downto 0); -- ? bits | ||
+ | sub : out std_logic_vector(? downto 0); -- ? bits | ||
+ | mult : out std_logic_vector(? downto 0); -- ? bits | ||
+ | div : out std_logic_vector(? downto 0); -- ? bits | ||
+ | resto : out std_logic_vector(? downto 0) -- ? bits | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture type_conv_arch of operadores is | ||
+ | -- Declarar os sinais necessarios para fazer as conversoes de tipo | ||
+ | begin | ||
+ | -- Inserir o codigo e definir o tamanho das saidas. | ||
+ | |||
+ | |||
+ | end architecture; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;Possíveis erros de compilação: | ||
+ | |||
+ | :Error (10482): VHDL error ... : object "std_logic_vector" is used but not declared | ||
+ | ::falta declarar a biblioteca '''ieee''' e usar o pacote '''std_logic_1164''' | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | :Error (10482): VHDL error ... : object "unsigned" is used but not declared | ||
+ | ::falta usar o pacote '''numeric_std''' | ||
+ | use ieee.numeric_std.all; | ||
+ | :Error (10344): VHDL expression error at ... : expression has 6 elements, but must have 3 elements | ||
+ | ::na atribuição feita, o objeto receptor o valor tem 3 elementos ("bits"), mas o resultado da expressão tem 6 elementos ("bits"). A solução é corrigir a definição do objeto ou usar a função '''resize''' para atribuir o número correto de elementos | ||
+ | |||
+ | ;Resultados da simulação funcional. | ||
+ | Após a simulação funcional, é necessário analisar os resultados obtidos em cada operação. A figura abaixo mostra 3 analises realizadas. | ||
+ | |||
+ | {{fig|3.8| Simulação funcional do Multiplicador/Divisor/Somador/Subtrator | OperadoresQSIM.png | 600 px |}} | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | ;Aula 18 (3 abr): | ||
+ | Nesta aula vamos estudar algumas estruturas e dicas adicionais para a sintese de circuitos em VHDL | ||
+ | ;A declaração de RECORD: | ||
+ | |||
+ | Enquanto que em um ARRAY todos os elementos devem ser obrigatoriamente do mesmo tipo, em um RECORD (Registro) os elementos podem ser de tipos diferentes. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | type memory_access is record | ||
+ | address : integer range 0 to 255; | ||
+ | block : integer range 0 to 3; | ||
+ | data : BIT_VECTOR(15 downto 0); | ||
+ | end record; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --Escrita no RECORD | ||
+ | constant endereco : memory_access := (34, 3, "010011110101011"); | ||
+ | |||
+ | --Acesso ao RECORD | ||
+ | signal address_lido : integer range 0 to 255; | ||
+ | signal block_lido : integer range 0 to 3; | ||
+ | signal data_lido : bit_vector(15 downto 0); | ||
+ | address_lido <= endereco.address; | ||
+ | block_lido <= endereco.block; | ||
+ | data_lido <= endereco.data; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | Um exemplo de uso do RECORD é: | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity record_example is | ||
+ | port ( | ||
+ | flag : out BIT_VECTOR(1 to 4); | ||
+ | sum : out natural range 0 to 15 | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture record_example of record_example is | ||
+ | type pair is record | ||
+ | a, b : natural range 0 to 7; | ||
+ | end record; | ||
+ | type stack is array (1 to 4) of pair; | ||
+ | constant matrix : stack := ((1, 2), (3, 4), (5, 6), (7, 0)); | ||
+ | begin | ||
+ | gen : for i in 1 to 4 generate | ||
+ | flag(i) <= '1' when matrix(i).a > matrix(i).b else '0'; | ||
+ | end generate; | ||
+ | sum <= matrix(1).a + matrix(1).b; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;As declarações de SUBTYPE: | ||
+ | |||
+ | A declaração de SUBTYPE é usada para restringir as declarações de TYPE. Abaixo estão alguns exemplos. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | subtype natural is integer range 0 to integer'HIGH; | ||
+ | subtype positive is integer range 1 to integer'HIGH; | ||
+ | subtype my_integer is integer range - 32 to 31; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;Como usar ARRAYs em portas?: | ||
+ | * Declaração do TYPE em PACKAGE | ||
+ | |||
+ | * Exemplo 3.8: Multiplexador com porta 1D x 1D.:: | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -----Package:------------ | ||
+ | -- File: my_pkg.vhd | ||
+ | ------------------------- | ||
+ | package my_data_types is | ||
+ | type a1Dx1D_bit_vector is array (0 to 3) of BIT_VECTOR(7 downto 0); | ||
+ | end my_data_types; | ||
+ | |||
+ | -----Main code: -------- | ||
+ | -- File: my_pkg.vhd | ||
+ | ------------------------- | ||
+ | use work.my_data_types.all; | ||
+ | |||
+ | entity mux1Dx1D is | ||
+ | port ( | ||
+ | x : in a1Dx1D_bit_vector; | ||
+ | sel : integer range 0 to 3; | ||
+ | y : out BIT_VECTOR(7 downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture pedroni of mux1Dx1D is | ||
+ | begin | ||
+ | y <= x(sel); | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Ver pag. 60 a 73 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;Uso da declaração ALIAS: | ||
+ | A declaração ALIAS define um nome alternativo para uma entidade ou objeto. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ALIAS new_name [: specifications] IS original_name [signature]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Alguns exemplos do uso do ALIAS para objetos (SIGNAL). | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | SIGNAL data_bus: STD_LOGIC_VECTOR(31 DOWNTO 0); | ||
+ | |||
+ | --bus1 is a new name for data_bus: | ||
+ | ALIAS bus1 IS data_bus; | ||
+ | |||
+ | --bus2 is a new name for data_bus, but with a modified range: | ||
+ | ALIAS bus2: STD_LOGIC_VECTOR(32 DOWNTO 1) IS data_bus; | ||
+ | |||
+ | --bus3 is another name for data_bus, with an ascending range: | ||
+ | ALIAS bus3: STD_LOGIC_VECTOR(1 TO 32) IS data_bus; | ||
+ | |||
+ | --upper_bus1 is a new name for the upper half of data_bus | ||
+ | ALIAS upper_bus1 IS data_bus(31 DOWNTO 16); | ||
+ | |||
+ | --upper_bus2 is a new name for the upper half of data_bus, but | ||
+ | --with a modified range: | ||
+ | ALIAS upper_bus2: STD_LOGIC_VECTOR(17 TO 32) IS data_bus(31 DOWNTO 16); | ||
+ | |||
+ | --lower_bus1 is a new name for the lower half of data_bus | ||
+ | ALIAS lower_bus1 IS data_bus(15 DOWNTO 0); | ||
+ | |||
+ | --lower_bus2 is a new name for the lower half of data_bus, but | ||
+ | --with a modified range: | ||
+ | ALIAS lower_bus2: STD_LOGIC_VECTOR(1 TO 16) IS data_bus(15 DOWNTO 0); | ||
+ | </syntaxhighlight> | ||
+ | :*Ver pag. 112 a 113 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | * Veja um exemplo de uso de alias no pacote numeric_std.vhd | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | function ADD_UNSIGNED (L, R: UNSIGNED; C: STD_LOGIC) return UNSIGNED is | ||
+ | constant L_LEFT: INTEGER := L'LENGTH-1; | ||
+ | alias XL: UNSIGNED(L_LEFT downto 0) is L; | ||
+ | alias XR: UNSIGNED(L_LEFT downto 0) is R; | ||
+ | variable RESULT: UNSIGNED(L_LEFT downto 0); | ||
+ | variable CBIT: STD_LOGIC := C; | ||
+ | begin | ||
+ | for I in 0 to L_LEFT loop | ||
+ | RESULT(I) := CBIT xor XL(I) xor XR(I); | ||
+ | CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I)); | ||
+ | end loop; | ||
+ | return RESULT; | ||
+ | end ADD_UNSIGNED; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* '''NOTA''': No exemplo acima, a CONSTANT L_LEFT recebe o tamanho do parâmetro (L), que pode ser qualquer. Esse tamanho é utilizado para criar dois ALIAS para os parâmetros L e R, utilizando uma indexação (L_LEFT DOWNTO 0). Com isso é possível dentro do FOR-LOOP criar os circuitos que realizam as operações lógicas que realizam a operação de soma. | ||
+ | |||
+ | ;Sobrecarga de operadores: | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | function "+" (a : integer, b : bit) return integer is | ||
+ | begin | ||
+ | if (b = '1') then return a + 1; | ||
+ | else | ||
+ | return a; | ||
+ | end if; | ||
+ | end "+"; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :: Ver pag. 91 a 108 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;Como estimar os tempos de propagação?: | ||
+ | * [[Medição de tempos de propagação em circuitos combinacionais]] | ||
+ | --> | ||
{{collapse bottom}} | {{collapse bottom}} |
Edição das 09h18min de 24 de novembro de 2020
MURAL DE AVISOS E OPORTUNIDADES DA ÁREA DE TELECOMUNICAÇÕES
Registro on-line das aulas
Unidade 1 - Introdução a disciplina
- 3 AULAS
Unidade 1 - Introdução a disciplina | ||||
---|---|---|---|---|
|
Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS
- 3 AULAS
Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS |
---|
Figura 2.1 - Fluxo simplificado do projeto de FPGA
library library_name;
use library_name.package_name.all;
entity entity_name is
[generic (
cons_name1: const_type const_value;
cons_name2: const_type const_value;
...
cons_nameN: const_type const_value);]
[port (
signal_name1: mode signal_type;
signal_name2: mode signal_type;
...
signal_nameN: mode signal_type);]
[declarative_part]
[begin
statement_part]
end [entity] [entity_name];
architecture arch_name of entity_name is
[declarative_part]
begin
statement_part
end [architecture] [arch_name];
library std;
use std.standard.all;
entity nand_gate is
port (a, b: in bit; x: out bit);
end entity;
architecture nome_arch of nand_gate is
begin
x <= a nand b;
end architecture;
-- Declaração das bibliotecas e pacotes
LIBRARY ieee;
USE ieee.std_logic_1164.all;
-- Especificação de todas as entradas e saídas do circuito
ENTITY flip_flop IS
PORT (d, clk, rst: IN STD_LOGIC;
q: OUT STD_LOGIC);
END;
-- Descrição de como o circuito deve funcionar
ARCHITECTURE flip_flop OF flip_flop IS
BEGIN
PROCESS (clk, rst)
BEGIN
IF (rst='1') THEN
q <= '0';
ELSIF (clk'EVENT AND clk='1') THEN
q <= d;
END IF;
END PROCESS;
END;
Figura 2.2 - Código RTL do Exemplo 2.2
Figura 2.3 - Technology Map do Exemplo 2.2
Figura 2.4 - Chip Planner do Exemplo 2.2
Figura 2.5 - RTL 4 FF
Figura 2.6 - Simulação Funcional de 4 FF 100ns Figura 2.7 - Simulação Temporal de 4 FF 100ns Note que na simulação funcional a mudança da saída Q ocorre no instante em que ocorre a borda de subida do clock ou no momento do reset. No entanto, no caso da simulação com timing, existe um atraso de ~6ns nestas mudanças. IMPORTANTE: Na prática normalmente não é necessário fazer a simulação temporal, pois através do Time Quest Report é possível verificar se o circuito atende as restrições de tempo.
create_clock -name CLK50MHz -period 50MHz [get_ports {*}]
ls /opt/altera/13.0sp1/quartus/libraries/vhdl/std
ls /opt/altera/13.0sp1/quartus/libraries/vhdl/ieee
ls /opt/altera/13.0sp1/quartus/libraries/vhdl/mentor/arithmetic (Mentor Graphics) ls /opt/altera/13.0sp1/quartus/libraries/vhdl/synopsys/ieee (Synopsys)
ls /opt/altera/16.0/quartus/libraries/vhdl/ieee/2008
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY registered_comp_add IS
PORT (clk: IN STD_LOGIC;
a, b: IN INTEGER RANGE 0 TO 7;
reg_comp: OUT STD_LOGIC;
reg_sum: OUT INTEGER RANGE 0 TO 15);
END;
ARCHITECTURE circuit OF registered_comp_add IS
SIGNAL comp: STD_LOGIC;
SIGNAL sum: INTEGER RANGE 0 TO 15;
BEGIN
comp <= '1' WHEN a>b ELSE '0';
sum <= a + b;
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk='1') THEN
reg_comp <= comp;
reg_sum <= sum;
END IF;
END PROCESS;
END;
Figura 2.10 - Código RTL do Exemplo 2.3 Note que na simulação funcional a mudança da saída Q ocorre no instante em que ocorre a borda de subida do clock ou no momento do reset. No entanto, no caso da simulação com timing, existe um atraso nestas mudanças. IMPORTANTE: Na prática normalmente não é necessário fazer a simulação temporal, pois através do Time Quest Report é possivel verificar se o circuito atende as restrições de tempo.
create_clock -name CLK50MHz -period 50MHz [get_ports {*}]
Video motivational para apreender FPGA, VHDL Microsoft's Bing* Intelligent Search with Intel® FPGAs |
Unidade 3 - Tipos de Dados e Operadores em VHDL
- 7 AULAS
Unidade 3 - Tipos de Dados e Operadores em VHDL | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ATUAL
-- Isso eh uma linha de comentario y <= a * b ; --o sinal y recebe o resultado da multiplicacao a x b
caracter: 'A' 'x' '#' (com aspas simples) string de caracteres: "IFSC" "teste" "teste123"
bit único: '0' '1' 'Z' (com aspas simples) vetor de bits: "0110" "101001Z" (com aspas duplas) vetor de 1 bit: "0" "1" (com aspas duplas) inteiros: 5 1101 1102 (sem aspas)
0 -> '0' 7 -> "0111" ou b"0111" ou B"0111" 1023 -> "001111111111" ou b"1111111111" ou B"1111111111"
44 -> 5*8^1 + 4*8^0 -> O"54" ou o"54" 1023 -> 1*8^3 + 7*8^2 + 7*8^1 + 7*8^0 -> o"1777" 8#1777#
1023 -> 3*16^2 + 15*16^1 + 15*16^0 = X"3FF" ou x"3FF" 16#3FF#
1023 -> 1023 ou 1_023 1000 -> 1000 ou 1_000 ou 1E3
5#320# (3*5^2 + 2*5^1 + 0*5^0) -> 85 3#201#E4 (2*3^2+0*3^1+1*3^0)*3^4 -> 1539
constant <constant_name> : <type> := <constant_value>;
A constant pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, PACKAGE_BODY, BLOCK, GENERATE, PROCESS, FUNCTION e PROCEDURE. -- Signal sem valor default
-- Para atribuir um valor a um signal use "<=" como operador.
signal <name> : <type>;
-- Signal com valor default
signal <name> : <type> := <default_value>;
-- Declarações comuns de signals
signal <name> : std_logic;
signal <name> : std_logic_vector(<msb_index> downto <lsb_index>);
signal <name> : integer;
signal <name> : integer range <low> to <high>;
O signal pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, BLOCK, GENERATE. Os sinais não podem ser declarados no código sequencial (PROCESS, FUNCTION e PROCEDURE), mas podem ser usados. -- Variables devem ser declarada em process ou subprogramas.
-- Para atribuir um valor a um variable use ":=" como operador.
-- Variable sem valor default.
variable <name> : <type>;
-- Variable com valor default.
variable <name> : <type> := <default_value>;
-- Declarações comuns de variables
variable <name> : std_logic;
variable <name> : std_logic_vector(<msb_index> downto <lsb_index>);
variable <name> : integer;
variable <name> : integer range <low> to <high>;
O variable (variável) só pode ser declarada e usada dentro do escopo no código sequencial (PROCESS, FUNCTION e PROCEDURE).
Exemplos de declaração de CONSTANT, SIGNAL, VARIABLE, inicializando o valor usando o agregados CONSTANT a: BIT_VECTOR(5 DOWNTO 0) := (OTHERS => '0'); -- "000000"
CONSTANT b: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', OTHERS => '1'); -- "01111111"
CONSTANT c: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', 6 DOWNTO 0 => '1'); -- "01111111"
CONSTANT d: BIT_VECTOR(7 DOWNTO 0) := "01111111";
SIGNAL e: STD_LOGIC_VECTOR(7 DOWNTO 0); -- Not initialized
SIGNAL f: STD_LOGIC_VECTOR(1 TO 8) := (2|3|8 => '1', 4 => 'Z', OTHERS => '0' ); -- "011Z0001"
VARIABLE g: BIT_VECTOR(1 TO 16); -- Not initialized
VARIABLE h: BIT_VECTOR(1 TO 16) := (1 TO 8 => '1', OTHERS => '0'); -- "1111111100000000"
A biblioteca standard.vhd define os tipos BIT, BIT_VECTOR, BOOLEAN, INTEGER, NATURAL, POSITIVE, CHARACTER, STRING. package standard is
type boolean is (false,true);
type bit is ('0', '1');
type severity_level is (note, warning, error, failure);
type integer is range -2147483647 to 2147483647;
type real is range -1.0E308 to 1.0E308;
type time is range -2147483648 to 2147483647
units
fs;
ps = 1000 fs;
ns = 1000 ps;
us = 1000 ns;
ms = 1000 us;
sec = 1000 ms;
min = 60 sec;
hr = 60 min;
end units;
subtype natural is integer range 0 to integer'high;
subtype positive is integer range 1 to integer'high;
type string is array (positive range <>) of character;
type bit_vector is array (natural range <>) of bit;
A biblioteca Std logic 1164.vhd define os tipos STD_(U)LOGIG, STD_(U)LOGIG_VECTOR. PACKAGE std_logic_1164 IS
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;
A biblioteca Std logic 1164.vhd ainda define algumas funções importantes como a rising_edge que determina se um sinal está na borda de subida (usado em sinais de clock). -------------------------------------------------------------------
-- 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_StdULogic ( b : BIT ) RETURN std_ulogic;
FUNCTION To_StdLogicVector ( b : BIT_VECTOR ) RETURN std_logic_vector;
-------------------------------------------------------------------
-- edge detection
-------------------------------------------------------------------
FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
-------------------------------------------------------------------
-- edge detection
-------------------------------------------------------------------
FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS
-- altera built_in builtin_rising_edge
BEGIN
RETURN (s'EVENT AND (To_X01(s) = '1') AND
(To_X01(s'LAST_VALUE) = '0'));
END;
A biblioteca Numeric std.vhd define os tipos UNSIGNED e SIGNED. package NUMERIC_STD is
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
type SIGNED is array (NATURAL range <>) of STD_LOGIC;
A biblioteca Numeric std.vhd ainda define os operadores (abs, "+", "-", "*", "\", rem, mod, sll, slr, ror, rol), comparações ("=", '/=', ">", ">=", "<", "<=") e operadores lógicos (not, and, nand, or, nor, xor, xnor) para os tipos SIGNED e UNSIGNED. Além disso também define algumas funções muito utilizadas como: --============================================================================
-- RESIZE Functions
--============================================================================
function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;
--============================================================================
-- Conversion Functions
--============================================================================
function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
function TO_INTEGER (ARG: SIGNED) return INTEGER;
function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
Figura 3.1 - Simulação de contador de vagas
|