Mudanças entre as edições de "DLP29006-Engtelecom (Diário) - Prof. Marcos Moecke"
Linha 2: | Linha 2: | ||
===Unidade 1 - Introdução a disciplina=== | ===Unidade 1 - Introdução a disciplina=== | ||
* 3 ENCONTROS | * 3 ENCONTROS | ||
− | {{collapse top | + | {{collapse top | Unidade 1 - Introdução a disciplina}} |
;Aula 1 (6 Out): | ;Aula 1 (6 Out): | ||
Linha 96: | Linha 96: | ||
===Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS=== | ===Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS=== | ||
* 5 ENCONTROS | * 5 ENCONTROS | ||
− | {{collapse top | + | {{collapse top| Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS}} |
;Aula 4 (19 out): | ;Aula 4 (19 out): | ||
Linha 415: | Linha 415: | ||
<!-- | <!-- | ||
− | |||
+ | {{collapse bottom}} | ||
− | * | + | ===Unidade 3 - Tipos de Dados e Operadores em VHDL=== |
+ | * 9 AULAS | ||
− | *''' | + | {{collapse top | expand=true | Unidade 3 - Tipos de Dados e Operadores em VHDL}} |
− | + | ;Aula 11 (9 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 caracteres, strings e números em VHDL. No circuito, os caracteres são representados através de bits de acordo com a [https://www.lookuptables.com/text/ascii-table tabela ASCII] básica (00 a 7F). A definição dessa tabela é feita o pacote '''[[standard.vhd]]''' da biblioteca '''std'''. | ||
+ | :*Caracteres (entre aspas simples) | ||
+ | caracter: 'A' 'x' '#' (com aspas simples) | ||
− | * | + | :*Palavras (entre aspas duplas), é definida no VHDL como um vetor de caracteres. |
+ | <syntaxhighlight lang=vhdl> | ||
+ | type string is array (positive range <>) of character; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | string: "IFSC" "teste" "teste123" | ||
− | *''' | + | :*Números em geral |
− | + | elemento ("bit") único: '0' '1' 'Z' (entre aspas simples) | |
+ | vetor de elementos ("bits"): "0110" "101001Z" (entre aspas duplas) | ||
+ | vetor de 1 elemento ("bit"): "0" "1" (entre aspas duplas) | ||
+ | inteiros: 5 1101 1102 (sem aspas) | ||
− | *'' | + | :*Números binários: |
− | + | 0 -> '0' | |
− | + | 7 (em base 2) -> "0111" ou b"0111" ou B"0111" | |
+ | 1023 (em base 2) -> "001111111111" ou b"1111111111" ou B"1111111111" | ||
− | * | + | :*Números octais: |
− | + | 44 (em base 8) -> 5*8^1 + 4*8^0 -> O"54" ou o"54" | |
− | + | 1023 (em base 8)-> 1*8^3 + 7*8^2 + 7*8^1 + 7*8^0 -> o"1777" 8#1777# | |
− | * | + | :*Números Hexadecimais: |
− | + | 1023 (em base 16) -> 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 | |
− | + | ::Cuidado ao usar o "_" pois algumas ferramentas não o reconhecem. | |
− | |||
− | + | :*Números em outras bases (de 2 a 16) | |
+ | 85 (em base 5) -> (3*5^2 + 2*5^1 + 0*5^0) -> 5#320# | ||
+ | 1539 (em base 3) -> (2*3^2+0*3^1+1*3^0)*3^4 -> 3#201#E4 | ||
− | *''' | + | *Tipos de dados em VHDL. |
+ | :*Objetos de VHDL: '''CONSTANT''', '''SIGNAL''', '''VARIABLE''', '''FILE'''. | ||
− | + | O objeto '''CONSTANT''' pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, PACKAGE_BODY, BLOCK, GENERATE, PROCESS, FUNCTION e PROCEDURE. | |
− | + | <syntaxhighlight lang=vhdl> | |
− | + | constant <constant_name> : <type> := <constant_value>; | |
− | |||
− | + | -- Declarações comuns de constantes | |
− | + | constant GND : std_logic := '0'; | |
− | + | constant VCC : std_logic := '1'; | |
+ | constant SSD_0 : std_logic_vector(0 to 6) := "1111110"; | ||
+ | constant MAX : natural := 44; | ||
+ | </syntaxhighlight> | ||
− | + | O objeto '''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> | |
− | + | -- 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 objeto '''VARIABLE''' (variável) só pode ser declarada e usada dentro do escopo no código sequencial (PROCESS, FUNCTION e PROCEDURE). | |
− | + | <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> | ||
− | + | :*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''''') | |
− | + | * 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> | <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> | </syntaxhighlight> | ||
− | |||
− | |||
− | + | A biblioteca [[Std logic 1164.vhd]] define os tipos STD_(U)LOGIG, STD_(U)LOGIG_VECTOR. | |
− | |||
− | |||
− | |||
− | |||
− | + | <syntaxhighlight lang=vhdl> | |
− | 0 - | + | 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> | <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> | </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> | <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> | </syntaxhighlight> | ||
− | + | :: Ver pag. 73 a 78 de <ref name="PEDRONI2010b"/> | |
− | + | :* 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 sem sinal || 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 sem sinal || sintetizável | ||
+ | |- | ||
+ | | SIGNED || std_logic_arith || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas com sinal || sintetizável (não é padrão, não utilizar) | ||
+ | |- | ||
+ | | UNSIGNED || std_logic_arith || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas sem sinal || sintetizável (não é padrão, não utilizar) | ||
+ | |- | ||
+ | | 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) |
− | + | *Função resize | |
− | |||
− | + | ;Aula 12 (16 nov): | |
− | A | + | * '''Desafio 1''' - Fazer um circuito que detecte se existe alguma vaga vazia em um lote de 9 vagas. A entrada '''x(n)''' está baixo '0' se a vaga está vazia, e alto '1' se tem carro. A saída '''y''' estará alta '1' sempre que houver uma ou mais vagas vazias, e em baixo '0' se não houver nenhuma vaga. |
− | + | *Faça a simulação do circuito para ver se está funcionando, | |
− | + | {{fig|3.1| Simulação do indicador de vagas | vagas9.png | 800 px |}} | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | A | + | * '''Desafio 2''' - Fazer um circuito que conte o número de vagas vazias em um lote de 9 vagas. A entrada '''x(n)''' está baixo '0' se a vaga está vazia, e alto '1' se tem carro. A saída '''CNT''' deverá mostrar em binário sem sinal o número de vagas vazias (O valor de '''CNT''' poderá ser entre 0 e 9). |
+ | |||
+ | *Faça a simulação do circuito para ver se está funcionando, | ||
+ | {{fig|3.2| Simulação do contador de vagas | cntvagas9.png | 800 px |}} | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | * 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> | <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> | <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> | ||
− | + | * '''Desafio 3''' - Fazer um circuito que detecte se existe alguma vaga vazia em um lote de 9 vagas. A entrada '''x(n)''' está baixo '0' se a vaga está vazia, e alto '1' se tem carro. A saída '''y''' estará alta '1' sempre que houver uma ou mais vagas vazias, e em baixo '0' se não houver nenhuma vaga. Inspirado na descrição VHDL acima, tente resolver esse problema usando ''don't care''. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | : | + | :'''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 12 (17 nov): | |
− | + | :* Tipos de dados: SIGNED e UNSIGNED | |
− | + | ||
− | + | :* Exemplo 3.3 Multiplicador de 4x4 bits (UN)SIGNED e INTEGER | |
− | + | ||
− | + | {{collapse top | expand=true| Código Multiplicador}} | |
− | + | <syntaxhighlight lang=vhdl> | |
− | + | --LIBRARY ieee; | |
− | + | --USE ieee.numeric_std.all; | |
− | + | --USE ieee.std_logic_1164.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}} | ||
+ | <center> | ||
+ | {{Mensagem | ||
+ | |indent = | ||
+ | |title= | ||
+ | |equation = <big> Ler e guardar a página sobre [[Aritmética com vetores em VDHL]] </big> | ||
+ | |cellpadding= 6 | ||
+ | |border | ||
+ | |border colour = #0073CF | ||
+ | |background colour=#F5FFFA}} | ||
+ | </center> | ||
− | + | :: Ver pag. 39 a 54 de <ref name="PEDRONI2010b"/> | |
− | : | + | ;Aula 13 (18 nov) - Aula prática de laboratório (individual): |
− | + | Nesta aula, cada aluno deverá seguir o seguinte roteiro: | |
− | < | + | ;Circuito 1: Utilizando VHDL, descreva um circuito que detecte se existe alguma vaga vazia em um lote de 4 vagas. A entrada '''x(n)''' está baixo '0' se a vaga está vazia, e alto '1' se tem carro. A saída '''y''' estará alta '1' sempre que houver uma ou mais vagas vazias, e em baixo '0' se não houver nenhuma vaga. |
− | |||
− | |||
− | + | :*Anote o número de elementos lógicos que foi utilizado para implementar o circuito. | |
− | + | :*Anote o número de pinos utilizados | |
− | + | :*Anote a família e código do dispositivo utilizado | |
− | + | :*Observe o diagrama RTL do circuito | |
− | + | :*Observe o diagrama do Technology Map do circuito | |
− | + | :*Faça a simulação do circuito para ver se está funcionando, e capture a tela que indica que o circuito funciona. A simulação devem mostrar pelo menos que havendo uma ou mais vagas a saída '''y''' está em '1', e caso não haja nenhuma vaga a saída deve estar em '0'. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | : | + | ;Circuito 2: Utilizando VHDL, descreva um circuito que conte o número de vagas vazias em um lote de 4 vagas. A entrada '''x(n)''' está baixo '0' se a vaga está vazia, e alto '1' se tem carro. A saída '''CNT''' deverá mostrar em binário sem sinal o número de vagas vazias (O valor de '''CNT''' poderá ser entre 0 e 4). |
− | + | :*Anote o número de elementos lógicos que foi utilizado para implementar o circuito. | |
− | + | :*Anote o número de pinos utilizados | |
− | :: | + | :*Anote a família e código do dispositivo utilizado |
+ | :*Observe o diagrama RTL do circuito | ||
+ | :*Observe o diagrama do Technology Map do circuito | ||
+ | :*Faça a simulação do circuito para ver se está funcionando, e capture a tela que indica que o circuito funciona. A simulação deve mostrar pelo menos uma situação na qual existe 0, 1, 2, 3 e 4 vagas. | ||
− | : | + | ;Circuito 3: Inspirado no "Exemplo 3.2 Circuito com saída ''don't care''" tente resolver esse problema usando ''don't care'', descreva um circuito que detecte se existe alguma vaga vazia em um lote de 4 vagas. A entrada '''x(n)''' está baixo '0' se a vaga está vazia, e alto '1' se tem carro. A saída '''y''' estará alta '1' sempre que houver uma ou mais vagas vazias, e em baixo '0' se não houver nenhuma vaga. |
+ | :*Anote o número de elementos lógicos que foi utilizado para implementar o circuito. | ||
+ | :*Anote o número de pinos utilizados | ||
+ | :*Anote a família e código do dispositivo utilizado | ||
+ | :*Observe o diagrama RTL do circuito | ||
+ | :*Observe o diagrama do Technology Map do circuito | ||
+ | :*Faça a simulação do circuito para ver se está funcionando, e capture a tela que indica que o circuito funciona. A simulação devem mostrar pelo menos que havendo uma ou mais vagas a saída '''y''' está em '1', e caso não haja nenhuma vaga a saída deve estar em '0'. | ||
− | + | ;Circuito 4: Verifique se você consegue imaginar uma descrição alternativa para o problema já tratado no Circuito 1 e 3. | |
− | + | :*Anote o número de elementos lógicos que foi utilizado para implementar o circuito. | |
− | + | :*Anote o número de pinos utilizados | |
+ | :*Anote a família e código do dispositivo utilizado | ||
+ | :*Observe o diagrama RTL do circuito | ||
+ | :*Observe o diagrama do Technology Map do circuito | ||
+ | :*Faça a simulação do circuito para ver se está funcionando, e capture a tela que indica que o circuito funciona. A simulação devem mostrar pelo menos que havendo uma ou mais vagas a saída '''y''' está em '1', e caso não haja nenhuma vaga a saída deve estar em '0'. | ||
− | + | ;Relatório Técnico: O relatório técnico deverá documentar o projeto e testes realizados, devendo ser entregue em pdf na atividade AE5 pelo moodle. Na AE5 também deve ser envidado o arquivo qar que contenha os 4 circuitos. Recomendo que utilize como nome dos arquivos VHDL algo como ''circuitoX.vhd'' e para os arquivos de simulação ''tb_circuitoX.vwf''. Todos os arquivos devem preferencialmente ficar em um único projeto e QAR. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | *Documentar o experimento em um relatório técnico que contenha no mínimo: | |
− | + | :*identificação (título, disciplina, data, autores); | |
− | + | :*introdução; | |
− | + | :*descrição do procedimento realizado para simular os circuitos; | |
− | + | :*resultados obtidos (com imagens dos itens importantes) e análise dos resultados, comparando as 4 soluções implementadas; | |
− | + | :*conclusão; | |
− | + | :*apêndice (coloque os códigos dos 4 circuitos implementados). | |
− | |||
− | |||
+ | ;Aula 14 (23 nov): | ||
+ | *Operadores em VHDL. | ||
+ | :* Operadores predefinidos: Atribuição, Lógicos, Aritméticos, Comparação, Deslocamento, Concatenação, "Matching". | ||
+ | ;Operadores lógicos: | ||
+ | São suportados nos tipos de dados: BIT, BIT_VECTOR, BOOLEAN, STD_(U)LOGIC, STD_(U)LOGIC_VECTOR, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para BOOLEAN_VECTOR, UFIXED, SFIXED e FLOAT. | ||
− | + | NOT | |
− | + | AND | |
− | + | NAND | |
− | + | OR | |
+ | NOR | ||
+ | XOR | ||
+ | XNOR | ||
− | + | Apenas o operador NOT tem precedência sobre os demais | |
− | + | y <= a AND b XOR c -- é equivalente a (a AND b) XOR c | |
+ | y <= NOT a AND b -- é equivalente a (NOT a) AND b. | ||
+ | y <= a NAND b -- é equivalente a NOT (a AND b) | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ;Operadores aritméticos: | |
+ | São suportados nos tipos de dados: INTEGER, NATURAL, POSITIVE, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para UFIXED, SFIXED e FLOAT. | ||
− | + | soma (+) | |
− | + | subtração (-) | |
− | + | multiplicação (*) | |
+ | divisão (/) | ||
+ | exponenciação (**) | ||
+ | valor absoluto (ABS) | ||
+ | resto (REM ''remainder'') | ||
+ | módulo (MOD) | ||
− | + | Não há restrições para síntese de circuitos com os operadores, exceto para '''"**"''' que necessita de expoente estático ('''a**5''') ou base estática ('''5**a'''). | |
− | |||
− | |||
− | + | O operador '''x/y''' é a divisão inteira com sinal. | |
− | + | :Exemplos: 9/10 = 0; -7/3 = -2; 9/-4 = -2; 20/(-4) = -5. | |
− | - | ||
− | + | O operador '''ABS x''' retorna o valor absoluto de x. | |
− | + | :Exemplos: ABS 6 = 6; ABS -11 = 11. | |
− | |||
+ | O operador '''x REM y''' retorna o resto de '''x/y''' com sinal de '''x'''. Esse operador realiza a operação '''x REM y = x - (x/y)*y'''. | ||
+ | :Exemplos: 9 REM 10 = 9; -7 REM 3 = -1; 9 REM -4 = 1; 20 REM (-4) = 0. | ||
− | + | O operador '''x MOD y''' retorna o resto de '''x/y''' com sinal de '''y'''. Esse operador realiza a operação '''x MOD y = x REM y + a*y''', onde '''a = 1''' quando o sinal de x é diferente do sinal de y, e '''a = 0''' se os sinais de x e y são iguais. | |
− | + | :Exemplos: 9 MOD 10 = 9 REM 10 = 9; -7 MOD 3 = 2; 9 REM -4 = -3; 20 REM (-4) = 0. | |
− | - | ||
− | |||
− | |||
− | |||
+ | :: Ver pag. 91 a 97 de <ref name="PEDRONI2010b"/> | ||
− | + | ;Exemplo de uso de operadores aritméticos: | |
+ | :* Exemplo conversor de binário para [[BCD - Binary-coded decimal]] de dois dígitos decimais (00 a 99). Para ilustrar são utilizadas os operadores DIVISOR e RESTO. 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 |}} | |
− | |||
− | |||
− | |||
− | |||
− | ; | + | ;Aula 15 (25 nov): |
− | + | *Algumas dicas para otimizar o tempo de propagação ou área ocupada (número de elementos lógicos) | |
− | :* | + | :* [[Uso de restrições de tempo e exceções no projeto]] |
− | :* | + | :* [[Medição de tempos de propagação em circuitos combinacionais]] |
− | :* | + | :* Usando o compilador do Quartus para otimizações. |
− | : | + | *Laboratório Remoto: |
− | :* | + | :*implementar as soluções do circuito bin2bcd e analisar o tempo de propagação e área ocupada. |
− | ; | + | ;Aula16 (30 nov): |
+ | * Operadores de deslocamento (SHIFT) | ||
+ | :*SLL (''Shift Left Logic'') - Deslocamento a esquerda lógico (preenchimento com '0's das posições a direita. | ||
+ | :*SRL (''Shift Right Logic'') - Deslocamento a direita lógico (preenchimento com '0's das posições a esquerda. | ||
+ | :*SLA (''Shift Left Arithmetic'') - Deslocamento a esquerda aritmético (posições liberadas da direita mantém o bit lsb) | ||
+ | :*SRA (''Shift Right Arithmetic'') - Deslocamento a esquerda aritmético (posições liberadas da esquerda mantém o bit msb) | ||
+ | :*ROL (''Rotate Left'') - Deslocamento circular a esquerda ( o bit que sai na esquerda é retornado na direita) | ||
+ | :*ROR (''Rotate Right'') - Deslocamento circular a direita ( o bit que sai na direita é retornado na esquerda) | ||
− | + | signal a: bit_vector(7 downto 0) := "01100101"; | |
− | + | y <= a SLL 2; -- y <= "100101'''00'''" (y <= a(5 downto 0) & "00";) | |
− | + | y <= a SLA 2; -- y <= "100101'''11'''" (y <= a(5 downto 0) & a(0) & a(0);) | |
− | + | y <= a ROR 2; -- y <= "'''01'''011001" (y <= a(1 downto 0) & a(7 downto 2);) | |
− | |||
− | |||
− | |||
+ | ::Esses operadores são suportados nos tipos BIT_VECTOR, (UN)SIGNED. Em VHDL 2008 também para BOOLEAN_VECTOR, STD_(U)LOGIG_VECTOR, UFIXED e SFIXED. | ||
− | + | * Operador de concatenação ('''&''') | |
− | + | ::Esse operador é suportado nos tipos BIT_VECTOR, STD_(U)LOGIG_VECTOR, STRING e (UN)SIGNED. Em VHDL 2008 também para INTEGER_VECTOR e BOOLEAN_VECTOR. | |
− | : | + | ::É utilizado para agrupar objetos como mostrado nos comentários dos exemplos anteriores |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | *Operadores de comparação | |
− | + | ::São suportados nos tipos de dados: BIT, BIT_VECTOR, BOOLEAN, INTEGER, NATURAL, POSITIVE, CHARACTER, STRING, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para BOOLEAN_VECTOR, INTEGER_VECTOR, UFIXED, SFIXED e FLOAT. | |
− | + | Igualdade (=) | |
− | + | Diferença (/=) | |
+ | Menor que (<) | ||
+ | Menor ou igual que (<=) | ||
+ | Maior que (>) | ||
+ | Maior ou igual que (>=) | ||
+ | *Operadores de comparação de associação (''matching comparison'') | ||
+ | ::Foram introduzidos no VHDL 2008, e tem o objetivo de tratar nos tipos baseados no STD_ULOGIC de forma igual os valores lógicos 'H'='1' e também 'L'='0', e 'X'='Z'='W'. São suportados nos tipos de dados: BIT, BIT_VECTOR, STD_(U)LOGIG, STD_(U)LOGIG_VECTOR, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para UFIXED, SFIXED. | ||
+ | Igualdade (?=) | ||
+ | Diferença (?/=) | ||
+ | Menor que (?<) | ||
+ | Menor ou igual que (?<=) | ||
+ | Maior que (?>) | ||
+ | Maior ou igual que (?>=) | ||
+ | Atributos em VHDL. | ||
+ | * 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> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ;Aula 17 (1 dez): | |
− | : | + | Atributos em VHDL. |
− | + | * Atributos de síntese: | |
− | + | :* '''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]. | ||
− | + | <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> | <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; | ||
+ | |||
+ | ATTRIBUTE keep: BOOLEAN; | ||
+ | ATTRIBUTE keep of a,b,c: SIGNAL IS FALSE; | ||
− | + | ATTRIBUTE preserve: BOOLEAN; | |
− | + | ATTRIBUTE preserve OF a, b, c: SIGNAL IS FALSE; | |
− | |||
− | + | ATTRIBUTE noprune: BOOLEAN; | |
− | + | ATTRIBUTE noprune OF a, b, c: SIGNAL IS FALSE; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | 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. | + | {{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 predefinidos são definidos no padrão [https://ieeexplore-ieee-org.ez130.periodicos.capes.gov.br/stamp/stamp.jsp?tp=&arnumber=8938196 1076-2019 - IEEE Standard for VHDL Language Reference Manual]. Esse documento pode ser acesso via o portal Periódicos Capes acesso CAFE. | |
− | * | + | Para cada atributo existe uma descrição completa como mostrado a seguir. |
− | : | + | P'LEFT Kind: Value. |
− | : | + | Prefix: Any prefix P that is appropriate for an object with a scalar type or subtype T, or an alias thereof, or that denotes any scalar type or subtype T. |
− | : | + | Result type: Same type as T. |
− | : | + | Result: The left bound of T. |
− | : | + | A seguir estão listados alguns dos atributos mais utilizados. |
− | |||
− | + | :*16.2.2 Predefined attributes of types and objects (p.270) | |
− | + | P'LEFT - The left bound of T. | |
− | + | P'RIGHT - The right bound of T. | |
− | + | P'HIGH - The upper bound of T. | |
+ | P'LOW - The lower bound of T. | ||
+ | P'ASCENDING - It is TRUE if T is defined with an ascending range; FALSE otherwise. | ||
+ | P'LENGTH - maximum(0, T’POS(T’HIGH) – T’POS(T’LOW) + 1) | ||
+ | P'RANGE - The range T'LEFT to T'RIGHT if the range of T is ascending, or the range T'LEFT downto T'RIGHT if the range of T is descending | ||
+ | P'REVERSE_RANGE - The range T'RIGHT downto T'LEFT if the range of T is ascending, or the range T'RIGHT to T'LEFT if the range of T is descending | ||
+ | T'POS(X) - The position number of the value of the parameter | ||
+ | T'VAL(X) - The value whose position number is the universal_integer value corresponding to X. | ||
− | :: | + | :*16.2.3 Predefined attributes of arrays (p.275) |
+ | A'LEFT [(N)] - Left bound of the Nth index range of A | ||
+ | A'RIGHT [(N)] - Right bound of the Nth index range of A | ||
+ | A'HIGH [(N)] - Upper bound of the Nth index range of A | ||
+ | A'LOW [(N)] - Lower bound of the Nth index range of A. | ||
+ | A'RANGE [(N)] - The range A'LEFT(N) to A'RIGHT(N) if the Nth index range of A is ascending, or the range A'LEFT(N) downto A'RIGHT(N) if the Nth index range of A is descending | ||
+ | A'REVERSE_RANGE [(N)] - The range A'RIGHT(N) downto A'LEFT(N) if the Nth index range of A is ascending, or the range A'RIGHT(N) to A'LEFT(N) if the Nth index range of A is descending. | ||
+ | A'LENGTH [(N)] - Number of values in the Nth index range | ||
+ | A'ASCENDING [(N)] - TRUE if the Nth index range of A is defined with an ascending range; FALSE otherwise. | ||
+ | |||
+ | :*16.2.4 Predefined attributes of signals (p. 277) | ||
+ | S'EVENT - A value that indicates whether an event has just occurred on signal S. | ||
+ | S'LAST_VALUE - For a signal S, if an event has occurred on S in any simulation cycle, S'LAST_VALUE returns the value of S prior to the update of S in the last simulation cycle in which an event occurred; otherwise, S'LAST_VALUE returns the current value of S. | ||
+ | |||
+ | :*16.2.5 Predefined attributes of named entities (p. 279) | ||
+ | E'SIMPLE_NAME - The simple name, character literal, or operator symbol of the named entity | ||
− | * | + | * 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> | ||
+ | ;Aula 18 (2 dez) - Laboratório remoto: | ||
+ | * AE7 - Estudo dos atributos de objetos e de síntese | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ;Aula19 (7 dez): | |
− | :: | + | :* 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]] | |
− | + | ||
− | |||
− | |||
− | |||
− | + | {{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> | <syntaxhighlight lang=vhdl> | ||
− | type | + | 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> | </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> | <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> | </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> | <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}} | ||
+ | ;Notas importantes: | ||
− | + | A retirada de fatias (SLICES) dos ARRAYs só pode ser feita se o array foi definido com um vetor de vetores (1Dx1D ou 1Dx1Dx1D). Ainda assim é necessário respeitar a ordem dos índices do VETOR. 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 19 (9 dez) - Laboratório remoto: | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | :* | + | ;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: mux1Dx1D.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"/> | ||
+ | |||
+ | ;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> | <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; | |
− | end | + | </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> | </syntaxhighlight> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Um exemplo de uso do RECORD é: | |
− | |||
− | <syntaxhighlight lang=vhdl> | + | <syntaxhighlight lang=vhdl> |
− | + | entity record_example is | |
− | entity | + | port ( |
− | + | flag : out BIT_VECTOR(1 to 4); | |
− | + | sum : out natural range 0 to 15 | |
− | + | ); | |
− | |||
− | |||
− | |||
− | |||
− | |||
end entity; | end entity; | ||
− | architecture | + | 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 | 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> | <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> | |
− | + | ||
− | + | ;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> | </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> | <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> | </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> | <syntaxhighlight lang=vhdl> | ||
− | + | function "+" (a : integer; b : bit) return integer is | |
− | + | begin | |
− | + | if (b = '1') then return a + 1; | |
− | + | else | |
− | + | return a; | |
− | end | + | end if; |
+ | end "+"; | ||
− | + | function "+" (a : integer; b : std_logic) 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"/> | |
− | + | * AE8 - Estudo dos arrays | |
− | |||
− | |||
− | |||
− | + | ;Aula 20 e 21 (14 e 15 dez): | |
− | + | * 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; | |
− | subtype | + | -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) |
− | + | -- Result: Computes "L mod R" where L and R are UNSIGNED vectors. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</syntaxhighlight> | </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> | <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> | </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 (10327): VHDL error at operadores.vhd(20): can't determine definition of operator ""+"" -- found 0 possible definitions | ||
+ | ::Falta definir uma soma para SLV. '''C_slv <= A_slv + Bslv''' | ||
+ | ::Fazer a operação em INTEGER ou UN(SIGNED). | ||
− | ; | + | :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 22 (16 dez) - Laboratório presencial | ||
+ | *[[DLP29006-Engtelecom(2021.2) - Prof. Marcos Moecke#AE9 - Calculadora básica implementada no kit DE2-115 | AE9 - Calculadora básica implementada no kit DE2-115]] | ||
− | + | ====ATUAL==== | |
− | * | + | ;Aula 23 e 24 (21 e 23 dez) |
+ | *Realize as simulações funcional do circuito usando o Modelsim. | ||
− | + | *'''PASSO 1a''': Abra o Modelsim | |
+ | /opt/altera/13.0sp1/modelsim_ae/bin/vsim | ||
− | * | + | *'''PASSO 1b''': Resete o Layout do Modelsim (caso tenha feito alguma modificação e não saiba como retornar ao original) (Layout > Reset). |
− | |||
− | |||
− | + | *'''PASSO 1c''': Mude para a pasta onde está o projeto, usando a barra de menu (File > Change Directory... [Escolha a pasta]. Ou via linha de comando na janela de transcript. | |
− | + | cd /home/nome_usuario/nome_pasta/... | |
− | |||
− | + | *'''PASSO 1d''': Confira se está na pasta correta | |
− | + | pwd | |
− | + | ls | |
− | : | + | *PASSO 1e: Compile o arquivo vhd do projeto. (Compile > Compile... selecione [n_Flip_Flop.vhd] e clique em [Compile]). Responda a [Create Library?] com [Yes]. Em seguida clique em [Done]. Ou |
− | + | vlib work | |
− | + | vcom -work work n_flip_flop.vhd | |
− | + | *'''PASSO 1f''': Inicie a simulação (Simulation > Start Simulation... na aba [Design] selecione a Entity [n_Flip_Flop] no Package work e clique em [OK]. Ou | |
− | + | vsim work.n_flip_flop | |
− | |||
+ | *'''PASSO 2a''': Inicie a criação dos sinais de entrada da Entity. Clique_direito sobre o nome da Entity na janela Library, e em seguida selecione [Create Wave]. Ou | ||
+ | wave create -pattern none -portmode in -language vhdl -range N 1 /n_flip_flop/d | ||
+ | wave create -pattern none -portmode in -language vhdl /n_flip_flop/clk | ||
+ | wave create -pattern none -portmode in -language vhdl /n_flip_flop/rst | ||
+ | wave create -pattern none -portmode out -language vhdl -range 1 N /n_flip_flop/q | ||
+ | |||
+ | Será aberta uma janela [Wave] na qual irão ser mostrados as 3 portas de entrada da Entity e a porta de saída. Clique sobre o sinal da porta de saída e [Delete], pois esse sinal não será editado. Aproveite para arrastar com o mouse os sinais na janela Wave para ficarem na seguinte ordem: rst, clk, d. | ||
− | + | *'''PASSO 2b''': Crie o sinal de rst como um pulso de valor '1' entre 20 e 30 ns. | |
− | |||
− | |||
− | + | Clique_direito sobre o sinal rst e selecione [Edit > Create/Modify Waveform] e escolha [Patterns = Constant], [Start Time = 0] [End Time = 1000] [Time Unit = ps] e clique em [Next], [Value = 0] e clique em [Finish]. Ou | |
− | + | wave modify -driver freeze -pattern constant -value 0 -starttime 0ps -endtime 1000ps Edit:/n_flip_flop/rst | |
− | |||
− | |||
− | + | Clique_direito sobre o sinal rst e selecione [Edit > Create/Modify Waveform] e escolha [Patterns = Constant], [Start Time = 20] [End Time = 30] [Time Unit = ps] e clique em [Next], [Value = 1] e clique em [Finish]. Ou | |
− | + | wave modify -driver freeze -pattern constant -value 1 -starttime 20ps -endtime 30ps Edit:/n_flip_flop/rst | |
− | |||
− | + | *'''PASSO 2c''': Crie o sinal de clk com um período de 100ps, iniciando em alto. | |
− | |||
− | |||
− | |||
− | + | Clique_direito sobre o sinal clk e selecione [Edit > Create/Modify Waveform] e escolha [Patterns = Clock], [Start Time = 0] [End Time = 1000] [Time Unit = ps] e clique em [Next], [Initial Value = 1], [Clock Period = 100ps], [Duty Cycle = 50] e clique em [Finish]. Ou | |
− | + | wave modify -driver freeze -pattern clock -initialvalue 1 -period 100ps -dutycycle 50 -starttime 0ps -endtime 1000ps Edit:/n_flip_flop/clk | |
− | |||
− | |||
− | + | *'''PASSO 2d''': Crie o sinal de d como sendo uma contagem entre "0000" e "1111" | |
− | |||
− | |||
− | + | Clique_direito sobre o sinal d e selecione [Edit > Create/Modify Waveform] e escolha [Patterns = Counter], [Start Time = 0] [End Time = 1000] [Time Unit = ps] e clique em [Next], [Start Value = 0000], [End Value = 1111], [Time Period = 120ps], [Counter Type = Range], [Count Direction = Up], [Step Count = 1], [Repeat = Forever] e clique em [Finish]. Ou | |
− | -- | + | wave modify -driver freeze -pattern counter -startvalue 0000 -endvalue 1111 -type Range -direction Up -period 120ps -step 1 -repeat forever -range 4 1 -starttime 0ps -endtime 1000ps Edit:/n_flip_flop/d |
− | |||
− | + | *'''PASSO 2e''': Insira o sinal de saída q na janela Wave. | |
− | * | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Clique sobre o sinal q na janela Objects e solte-o na janela Wave. Ao final desses passos a janela Wave deverá estar conforme mostrado abaixo: | |
+ | {{fig|2.8|Edição do Waveform de 4 FF 1000ns no Modelsim| MODELSIM_4FF_Edit.png| 800 px |}} | ||
− | + | *'''PASSO 3''': Realize a simulação de 1000 ps | |
− | |||
− | + | :Opção 1: Clique 10 vezes sobre o icone [Run] ou [F9] | |
− | + | :Opção 2: Digite 10 vezes o comando run na janela Transcript (cada run dura o tempo indicado ao lado esquerdo do icone [Run] | |
− | + | :Opção 3: Digite o comando run 1000 ps | |
− | + | :Opção 4: Digite o comando run -all (será executado o tempo necessario para concluir os sinais que foram desenhados. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | *'''PASSO 4''': Análise da simulação | |
− | |||
− | |||
− | |||
+ | Selecione com o shift_clique_esquerdo do mouse os sinas d e q (barramentos de 4 bits) e em seguida clique_direito e selecione [radix > unsigned]. A janela Wave deverá estar conforme mostrado abaixo: | ||
+ | {{fig|2.9|Simulação funcional de 4 FF 1000ns no Modelsim| MODELSIM_4FF_Simul.png| 800 px |}} | ||
− | + | *Note que a saída q está com (Forcing Unknown - (X em vermelho) entre 0 e 20 ps. Isso ocorre pois antes de aplicar o RESET o Flip Flop tem valor desconhecido. Por isso é sempre importante aplicar um RESET logo ao iniciar a simulação de um circuito sequencial. | |
+ | *Note que as mudanças na saída q ocorrem sempre na transição de subida do sinal do CLOCK. Mudanças que ocorrem na entrada do sinal d não afetam a saída. | ||
+ | *Experimente mudar o sinal de entrada d com períodos diferentes (e.g. 60ps) e repita a simulação. | ||
+ | *Inclua um pequeno pulso de RESET na instante 530ps. | ||
+ | |||
+ | *'''PASSO 5''': Criação de um teste bench com arquivo .do | ||
+ | Use os comandos da janela de transcript para criar um arquivo tb_FF.do que permite repetir de forma automatica o teste realizado. | ||
+ | <syntaxhighlight lang=tcl> | ||
+ | ################################ | ||
+ | # FILE : tb_FF.do | ||
+ | # AUTOR: Marcos Moecke | ||
+ | # DATA : 14 de agosto de 2019 | ||
+ | ################################ | ||
− | + | #criacao da library work | |
+ | vlib work | ||
− | + | #compilacao da entity nome.vhd (nao necessita ser compilado no quartus II) | |
+ | vcom -work work n_flip_flop.vhd | ||
− | + | #simulacao na entity nome.vhd | |
− | + | vsim work.n_flip_flop | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | : | + | #edicao do sinal rst |
− | : | + | wave create -pattern none -portmode in -language vhdl /n_flip_flop/rst |
− | + | wave modify -driver freeze -pattern constant -value 0 -starttime 0ps -endtime 1000ps Edit:/n_flip_flop/rst | |
− | + | wave modify -driver freeze -pattern constant -value 1 -starttime 20ps -endtime 30ps Edit:/n_flip_flop/rst | |
− | + | ||
+ | #edicao do sinal clock | ||
+ | wave create -pattern none -portmode in -language vhdl /n_flip_flop/clk | ||
+ | wave modify -driver freeze -pattern clock -initialvalue 1 -period 100ps -dutycycle 50 -starttime 0ps -endtime 1000ps Edit:/n_flip_flop/clk | ||
+ | |||
+ | #edicao do sinal d | ||
+ | wave create -pattern none -portmode in -language vhdl -range N 1 /n_flip_flop/d | ||
+ | wave modify -driver freeze -pattern counter -startvalue 0000 -endvalue 1111 -type Range -direction Up -period 120ps -step 1 -repeat forever -range 4 1 -starttime 0ps -endtime 1000ps Edit:/n_flip_flop/d | ||
+ | |||
+ | #inclusao do sinal de saida q (como BINARY) | ||
+ | add wave -position end sim:/n_flip_flop/q | ||
+ | |||
+ | #inclusao do sinal de saida q (como UNSIGNED) | ||
+ | add wave -position end -radix hexadecimal sim:/n_flip_flop/q | ||
+ | |||
+ | #execucao da simulacao inteira | ||
+ | run -all | ||
− | + | #reinicio do tempo e simulacao | |
− | + | restart | |
− | + | #execucao da simulacao por 1000 ps | |
+ | run 1000 ps | ||
+ | </syntaxhighlight> | ||
− | + | *Para conhecer melhor o MODELSIM GRAPHICAL WAVEFORM EDITOR, consulte o [[Media:ModelsimGraphicalWaveformEditor.pdf | INTRODUCTION TO SIMULATION OF VHDL DESIGNS USING MODELSIM GRAPHICAL WAVEFORM EDITOR]] | |
− | + | ||
− | *[[ | ||
+ | --> | ||
{{collapse bottom}} | {{collapse bottom}} | ||
Edição das 09h21min de 21 de dezembro de 2021
Registro on-line das aulas
Unidade 1 - Introdução a disciplina
- 3 ENCONTROS
Unidade 1 - Introdução a disciplina | ||||
---|---|---|---|---|
|
Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS
- 5 ENCONTROS
Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS |
---|
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;
Exemplo de descrição de um multiplexador de 4 entradas entity mux_novo is
port
(
-- Input ports
X: in bit_vector (3 downto 0);
S : in bit_vector (1 downto 0);
-- Output ports
Y : out bit
);
end entity mux_novo;
-- Implementação com lógica pura
architecture v_logica_pura of mux_novo is
begin
Y <= (X(0) and (not S(1)) and (not S(0))) or
(X(1) and (not S(1)) and (S(0))) or
(X(2) and (S(1)) and (not S(0))) or
(X(3) and (S(1)) and (S(0)));
end architecture Logica_pura;
-- Implementação com WHEN ELSE
architecture v_WHEN of mux_novo is
begin
Y <= X(0) when S = "00" else
X(1) when S = "01" else
X(2) when S = "10" else
X(3);
end architecture v_WHEN;
-- Implementação com WITH SELECT
architecture v_WITH_SELECT of mux_novo is
begin
with S select
Y <= X(0) when "00", -- note o uso da ,
X(1) when "01",
X(2) when "10",
X(3) when others; -- note o uso de others, para todos os demais valores.
-- Não pode ser substituido por "11" mesmo que o signal seja bit_vector.
end architecture v_WITH_SELECT;
-- Implementação com IF ELSE
architecture v_IF_ELSE of mux_novo is
begin
-- Uma arquitetura vazia como essa é denominada de STUB,
-- Pode ser utilizada em um projeto durante para conferir as conexões externas.
-- Posteriormente a arquitetura será descrita.
end architecture v_IF_ELSET;
-- Design Unit que associa a architecture com a entity
configuration cfg_ifsc of mux_novo is
-- for v_WITH_SELECT end for;
for v_WHEN end for;
end configuration;
Figura 2.1 - Código RTL do mux 4x1 v_logica_pura Figura 2.2 - Código RTL do mux 4x1 v_WHEN Figura 2.3 - Código RTL do mux 4x1 v_WITH_SELECT
Figura 2.4 - Technology Map do mux 4x1 para a família Cyclone
Figura 2.5 - Elemento Lógico usado no mux 4x1 para a família Cyclone (node properties)
No entanto se utilizarmos um dispositivo FPGA da família Stratix III, que tem LUT tem 6 entradas, será necessário apenas 1 LE, conforme ilustrado a seguir. Figura 2.5 - Technology Map do mux 4x1 para a família Stratix III
-- 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_v1 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 ENTITY;
ARCHITECTURE ifsc_v1 OF registered_comp_add_v1 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 ARCHITECTURE;
Figura 2.10 - Código RTL do Exemplo 2.3 Preparação para o Laboratório de programação de um contador. Problema do repique das chaves. Ver Dicas de como eliminar o repique das chaves mecânicas Ler sobre o problema do repique das chaves mecânicas A Guide to Debouncing
No dia 10 foram realizados os passos 1 a 2. Mas como houve um erro na definição da pinagem da chave usada para o clock, com isso, ao final do lab o circuito não funcionou. No dia 12 será refeito o circuito, testado novamente (Passo 3) e acrescentado o circuito de anti-repique sugerido
|
Avaliações
Nas avaliações A1 e A2 serão realizadas de forma presencial e vocês poderão consultar apenas as folhas entregues:
- VHDL Quick Reference - SynthWorks
- VHDL Types and Operators Quick Reference - SynthWorks
- ModelSim Quick Reference - SynthWorks
- Tabelas das figuras 3.6, 3.10 e 4.1 do livro do Pedroni.
- Arquivo:Numeric std conversions.png
- Dica use também como fonte de consulta os templates do Quartus.
- Ao final das avaliações o aluno deverá enviar a avaliação para a plataforma Moodle com os arquivos solicitados.
ATIVIDADE EXTRA-CLASSE (AE)
A soma das atividades Extra-classe será correspondente a 25% do conceito final na disciplina. A entrega das mesmas será feita pelo Moodle da disciplinas, e cada dia de atraso irá descontar 0,2 na nota da atividade. Muitas dessas atividades também possuem BÔNUS que são adicionados aos conceitos das avaliações A1 e A2. Para os BÔNUS só serão considerados projetos entregues no prazo.
AE1 - Palavras-cruzadas INTRODUÇÃO
AE1 - Palavras-cruzadas INTRODUÇÃO |
---|
|
AE2 - Conhecendo os dispositivos lógicos programáveis
AE2 - Conhecendo os dispositivos lógicos programáveis |
---|
|
AE3 - SNCT 2021 | 5G e Conectividade com IoT
AE3 - SNCT 2021 |
---|
5G e Conectividade com IoT |
Após assistir a palestra e debate do dia de hoje, seguem algumas perguntas que devem ser respondidas em um PDF.
|
AE4 - Programação do kit Mercurio IV
AE4 - Programação do kit Mercurio IV |
---|
entity counter is
generic (WIDTH : in natural := 4);
port (
RST : in std_logic;
CLK : in std_logic;
LOAD : in std_logic;
DATA : in std_logic_vector(WIDTH-1 downto 0);
R0 : out std_logic
Q : out std_logic_vector(WIDTH-1 downto 0));
end entity;
architecture ifsc_v1 of counter is
signal Q_aux : std_logic(WIDTH-1 downto 0);
begin
process(RST,CLK) is
begin
if RST = '1' then
Q_aux <= (others => '0');
elsif rising_edge(CLK) then
if LOAD= '1' then
Q_aux <= DATA;
else
Q_aux <= std_logic_vector(unsigned(Q_aux) + 1);
end if;
end if;
end process;
-- Adaptacao feita devido a matriz de leds acender com ZERO
Q <= not Q_aux;
-- Para acender um led eh necessario colocar ZERO na linha correspondente da matriz.
R0 <= '0';
end architecture;
CLK: PIN_Y17 ou PIN_V21 DATA[3]: PIN_H18 DATA[2]: PIN_H20 DATA[1]: PIN_K21 DATA[0]: PIN_J21 LOAD: PIN_Y22 Q[3]: PIN_J6 Q[2]: PIN_K8 Q[1]: PIN_J8 Q[0]: PIN_L8 RST: PIN_W21 R0: PIN_F10
-- insira na declaração das portas da entity a linha
LCD_BACKLIGHT: std_logic;
-- insira na architecture a linha
LCD_BACKLIGHT <= '0';
LCD_BACKLIGHT: PIN_V10
entity COUNTER_db is
...
CLK50MHz : in std_logic;
...
end entity
architecture ifsc_v2 of COUNTER_db is
...
signal CLK_db: std_logic := '0';
...
begin
-- debouncer de 10ms
process (CLK50MHz, CLK, RST, CLK_db) is
constant max_cnt: natural := 500000; -- 500000 10ms para clk 20ns
variable cnt_db : integer range 0 to max_cnt-1;
begin
if (RST = '1') then
cnt_db := 0;
CLK_db <= '0';
elsif ((CLK = '0') and (CLK_db = '0')) or
((CLK = '1') and (CLK_db = '1')) then
cnt_db := 0;
elsif (rising_edge(CLK50MHz)) then
if (cnt_db = max_cnt - 1) then
CLK_db <= not CLK_db;
else
cnt_db := cnt_db + 1;
end if;
end if;
end process;
...
-- Troque no process(RST,CLK) a entrada '''CLK''' do circuito anterior pela entrada '''CLK_db'''
CLK50MHz: PIN_T1
create_clock -name CLK50MHz -period 50MHz [get_ports -no_case {clk*}]
|
AE5 - Desafio das vagas de garagem
AE5 - Desafio das vagas de garagem |
---|
|
AE6 - Conversor de binário para BCD
AE7 - Estudo dos atributos de objetos e de síntese
AE8 - Estudo dos Arrays
AE8 - Estudo dos Arrays |
---|
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;
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;
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;
--Acessando uma linha de uma matriz
gen1 : for j in 1 to 4 generate
slice3(j) <= table(row, j);
end generate;
-- Acessando uma coluna de uma matriz
gen2 : for i in 1 to 3 generate
slice4(i) <= table(i, column);
end generate;
|
AE9 - Calculadora básica implementada no kit DE2-115
AE9 - Calculadora básica implementada no kit DE2-115 |
---|
|