Mudanças entre as edições de "DLP29006-Engtelecom(2019-2) - Prof. Marcos Moecke"
(→ATUAL) |
|||
(99 revisões intermediárias por 3 usuários não estão sendo mostradas) | |||
Linha 1: | Linha 1: | ||
{{DivulgueEngtelecom}} | {{DivulgueEngtelecom}} | ||
==Registro on-line das aulas== | ==Registro on-line das aulas== | ||
− | |||
===Unidade 1 - Introdução a disciplina=== | ===Unidade 1 - Introdução a disciplina=== | ||
* 3 AULAS | * 3 AULAS | ||
+ | |||
+ | {{collapse top|Unidade 1 - Introdução a disciplina}} | ||
;Aula 1 (29 jul): | ;Aula 1 (29 jul): | ||
Linha 76: | Linha 77: | ||
{{collapse bottom}} | {{collapse bottom}} | ||
− | |||
− | |||
===Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS=== | ===Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS=== | ||
* 3 AULAS | * 3 AULAS | ||
+ | {{collapse top| Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS}} | ||
;Aula 4 (5 ago): | ;Aula 4 (5 ago): | ||
Linha 86: | Linha 86: | ||
* Estrutura do código VHDL | * Estrutura do código VHDL | ||
:* Declaração das bibliotecas e pacotes '''LIBRARY''' / '''PACKAGE''' | :* Declaração das bibliotecas e pacotes '''LIBRARY''' / '''PACKAGE''' | ||
− | < | + | <syntaxhighlight lang=vhdl> |
library library_name; | library library_name; | ||
use library_name.package)name.all; | use library_name.package)name.all; | ||
− | </ | + | </syntaxhighlight> |
:* '''ENTITY''' | :* '''ENTITY''' | ||
− | < | + | <syntaxhighlight lang=vhdl> |
entity entity_name is | entity entity_name is | ||
[generic ( | [generic ( | ||
Linha 108: | Linha 108: | ||
statement_part] | statement_part] | ||
end [entity] [entity_name]; | end [entity] [entity_name]; | ||
− | </ | + | </syntaxhighlight> |
:* '''ARCHITECTURE''' | :* '''ARCHITECTURE''' | ||
− | < | + | <syntaxhighlight lang=vhdl> |
architecture arch_name of entity_name is | architecture arch_name of entity_name is | ||
[declarative_part] | [declarative_part] | ||
Linha 117: | Linha 117: | ||
statement_part | statement_part | ||
end [architecture] [arch_name]; | end [architecture] [arch_name]; | ||
− | </ | + | </syntaxhighlight> |
+ | |||
* Exemplo - Declaração de uma porta NAND em VHDL | * Exemplo - Declaração de uma porta NAND em VHDL | ||
+ | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
library std; | library std; | ||
Linha 242: | Linha 244: | ||
<center> Figura 2.5 - RTL 4 FF </center> | <center> Figura 2.5 - RTL 4 FF </center> | ||
− | + | ||
− | ;Aula 7 (14 ago): | + | ;Aula 7 e 8 (14 e 16 ago): |
<big> Video motivational para apreender FPGA, VHDL [https://youtu.be/ecyyZ6zTLic Microsoft's Bing* Intelligent Search with Intel® FPGAs] </big> | <big> Video motivational para apreender FPGA, VHDL [https://youtu.be/ecyyZ6zTLic Microsoft's Bing* Intelligent Search with Intel® FPGAs] </big> | ||
Linha 262: | Linha 264: | ||
*Realize as simulações funcional do circuito usando o Modelsim. | *Realize as simulações funcional do circuito usando o Modelsim. | ||
− | *PASSO 1a: Abra o Modelsim | + | *'''PASSO 1a''': Abra o Modelsim |
/opt/altera/13.0sp1/modelsim_ae/bin/vsim | /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 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. | + | *'''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/... | cd /home/nome_usuario/nome_pasta/... | ||
− | *PASSO 1d: Confira se está na pasta correta | + | *'''PASSO 1d''': Confira se está na pasta correta |
pwd | pwd | ||
ls | ls | ||
Linha 278: | Linha 280: | ||
vcom -work work n_flip_flop.vhd | 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 | + | *'''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 | 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 | + | *'''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 -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/clk | ||
Linha 289: | Linha 291: | ||
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. | 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. | + | *'''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 | 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 | 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 = | + | 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 | 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. | + | *'''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 | 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 | 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" | + | *'''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 = | + | 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 | 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. | + | *'''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: | 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: | ||
Linha 314: | Linha 316: | ||
<center> Figura 2.7 - Edição do Waveform de 4 FF 1000ns no Modelsim </center> | <center> Figura 2.7 - Edição do Waveform de 4 FF 1000ns no Modelsim </center> | ||
− | *PASSO 3: Realize a simulação de 1000 ps | + | *'''PASSO 3''': Realize a simulação de 1000 ps |
:Opção 1: Clique 10 vezes sobre o icone [Run] ou [F9] | :Opção 1: Clique 10 vezes sobre o icone [Run] ou [F9] | ||
Linha 321: | Linha 323: | ||
:Opção 4: Digite o comando run -all (será executado o tempo necessario para concluir os sinais que foram desenhados. | :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 | + | *'''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: | 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: | ||
Linha 333: | Linha 335: | ||
*Inclua um pequeno pulso de RESET na instante 530ps. | *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. | 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> | <syntaxhighlight lang=tcl> | ||
Linha 428: | Linha 430: | ||
--> | --> | ||
{{collapse bottom}} | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 3 - Tipos de Dados e Operadores em VHDL=== | ||
+ | * 7 AULAS | ||
+ | |||
+ | {{collapse top | Unidade 3 - Tipos de Dados e Operadores em VHDL}} | ||
+ | |||
+ | ;Aula 7 (19 ago): | ||
+ | *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> | ||
+ | |||
+ | |||
+ | ;Aula 8 (21 ago): | ||
+ | :* 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.0E-38] || 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) | ||
+ | |||
+ | :* Exemplo 3.1 Buffer Tri-state | ||
+ | {{collapse top | Buffer tri_state}} | ||
+ | <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> | ||
+ | {{collapse bottom}} | ||
+ | ::* 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" | ||
+ | |||
+ | {{collapse top | Saída 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> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | :* 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 9 (26 ago): | ||
+ | |||
+ | :* 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]] | ||
+ | |||
+ | :::Exemplos Ex 3.5, Ex 3.6 e Ex 3.7 | ||
+ | :* RECORD e SUBTYPE | ||
+ | |||
+ | ;Aula 13 (30 ago): | ||
+ | :* Uso de ARRAYs em portas | ||
+ | ::* Declaração do TYPE em PACKAGE | ||
+ | ::* Exemplo 3.8: Multiplexador com porta 1D x 1D.:: | ||
+ | Ver pag. 60 a 73 de <ref name="PEDRONI2010b"/> | ||
+ | *Qualificação de tipos, conversão de tipos (automática, casting e funções de conversão). | ||
+ | :* Resumo das funções de conversão de tipos (Tabela 3.10) e ver [[Aritmética com vetores em VDHL]] | ||
+ | |||
+ | <!-- | ||
+ | :* Exercício: Multiplicador/Divisor/Somador/Subtrator com sinal e sem sinal (entradas do tipo STD_LOGIC VECTOR) | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | LIBRARY ieee; | ||
+ | USE ieee.std_logic_1164.all; | ||
+ | USE ieee.numeric_std.all; | ||
+ | |||
+ | ENTITY operadores IS | ||
+ | PORT ( | ||
+ | a, b: IN STD_LOGIC_VECTOR(3 DOWNTO 0); | ||
+ | mult: OUT STD_LOGIC_VECTOR(? DOWNTO 0); | ||
+ | div: OUT STD_LOGIC_VECTOR(? DOWNTO 0); | ||
+ | sum: OUT STD_LOGIC_VECTOR(? DOWNTO 0); | ||
+ | sub: OUT STD_LOGIC_VECTOR(? DOWNTO 0); | ||
+ | ); | ||
+ | END ENTITY; | ||
+ | |||
+ | ARCHITECTURE type_conv_arch OF operadores IS | ||
+ | BEGIN | ||
+ | -- Inserir o código e definir o tamanho das saidas. | ||
+ | END ARCHITECTURE; | ||
+ | </syntaxhighlight> | ||
+ | --> | ||
+ | * '''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 | ||
+ | *Faça a simulação do circuito para ver se está funcionando, | ||
+ | [[Arquivo:vagas5.png | 800px]] | ||
+ | :: Ver função resize | ||
+ | :: Ver pag. 73 a 78 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;Aula 14 e 15 (02 e 04 set): | ||
+ | |||
+ | *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> | ||
+ | <center> | ||
+ | [[Arquivo:bin2bcdDU_RTL.png| 600px]] | ||
+ | |||
+ | Figura - RTL do conversor de Binário para BCD com 2 digitos | ||
+ | |||
+ | [[Arquivo:bin2bcdDU_modelsim.png| 1000px]] | ||
+ | |||
+ | Figura - Simulação do conversor de Binário para BCD com 2 digitos | ||
+ | </center> | ||
+ | :* Sobrecarga de operadores | ||
+ | |||
+ | :: Ver pag. 91 a 108 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | *Realizar e entregar pelo Moodle a '''[https://moodle.sj.ifsc.edu.br/mod/assign/view.php?id=5825 atividade AE1 - Conversor de binário para BCD]''' que está marcado(a) para segunda, 23 setembro, 07:00. Essa atividade todos deverão realizar, mas existem dois BONUS para quem fizer o circuito com menor número de elementos lógicos e menor atraso de propagação. | ||
+ | |||
+ | |||
+ | :Ver: [[Medição de tempos de propagação em circuitos combinacionais]] | ||
+ | |||
+ | |||
+ | ;Aula 16 (9 set): | ||
+ | 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]. | ||
+ | |||
+ | <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> | ||
+ | |||
+ | :::* 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'''. | ||
+ | <center> [[Arquivo:Ex4_5_NoAttribute.png | Sem Attribute| 400 px]] <br> '''Fig 12. Technology Map do Circuito sem Attribute'''</center> | ||
+ | <center> [[Arquivo:Ex4_5_PreserveAttribute.png| Preserve (or Keep) Attribute |400 px]] <br> '''Fig 13. Technology Map do Circuito com Attribute Preserve (or Keep) '''</center> | ||
+ | <center> [[Arquivo:Ex4_5_NopruneAttribute.png| Noprune Attribute| 400 px]] <br> '''Fig 14. Technology Map do Circuito com Attribute Noprune '''</center>:: Ver pag. 91 a 111 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | :* 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> | ||
+ | Exemplo: | ||
+ | |||
+ | |||
+ | ;Aula 17 (11 set): | ||
+ | |||
+ | Uso da instrução ALIAS. | ||
+ | ::*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. | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 4 - Código Concorrente=== | ||
+ | * 4 AULAS | ||
+ | |||
+ | {{collapse top| Unidade 4 - Código Concorrente}} | ||
+ | |||
+ | ;Aula 17 (11 set): | ||
+ | *Código Concorrente. | ||
+ | :* Uso de Operadores | ||
+ | :* instrução WHEN-ELSE (WHEN) | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | <optional_label>: <target> <= | ||
+ | <value> when <condition> else | ||
+ | <value> when <condition> else | ||
+ | <value> when <condition> else | ||
+ | ... | ||
+ | <value>; | ||
+ | </syntaxhighlight> | ||
+ | ::*Importante: O último ELSE deve cobrir todos os demais valores para evitar a criação de LATCHES. | ||
+ | ::* No QuartusII existe um template pronto para ser utilizado em: '''[Edit > Insert Template > Language templates = VHDL (+) > Constructs (+) > Concurrent Statemens (+) > Conditional Signal Assignment]''' | ||
+ | |||
+ | :* instrução WITH-SELECT-WHEN (SELECT) | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | <optional_label>: with <expression> select | ||
+ | <target> <= | ||
+ | <value> when <choices>, | ||
+ | <value> when <choices>, | ||
+ | <value> when <choices>, | ||
+ | ... | ||
+ | <value> when others; | ||
+ | </syntaxhighlight> | ||
+ | ::*Importante: O valor deve cobrir todas as demais possibilidades usando WHEN OTHERS para evitar a criação de LATCHES. | ||
+ | ::* No QuartusII existe um template pronto para ser utilizado em: '''[Edit > Insert Template > Language templates = VHDL (+) > Constructs (+) > Concurrent Statemens (+) > Selected Signal Assignment]'''. '''Mas ATENÇÃO, faltam as virgulas após cada escolha'''. | ||
+ | |||
+ | :* Exemplo 5.1 + 5.2 mux: com 3 tipos de arquiteturas (com portas, com WHEN-ELSE, com WITH-SELECT) | ||
+ | ::Verifique os três circuitos considerando as entradas x0 a x3 e a saída y com apenas um elemento. | ||
+ | ::Modifique os circuitos para que tenham as entradas x0 a x3 e a saída y com 4 elementos. | ||
+ | :::No caso do uso de WHEN-ELSE e WITH-SELECT é só alterar o tamanho dos vetores STD_LOGIC_VECTOR. | ||
+ | :::Qual é a solução para a descrição com portas? | ||
+ | :* Para selecionar uma entre várias arquiteturas para a mesma ENTITY use a CONFIGURATION. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | CONFIGURATION which_mux OF mux IS | ||
+ | FOR Operator_only END FOR; | ||
+ | -- FOR with_WHEN END FOR; | ||
+ | -- FOR with_SELECT END FOR; | ||
+ | END CONFIGURATION; | ||
+ | </syntaxhighlight> | ||
+ | ::Ver pag. 121 a 127 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | |||
+ | ;Aula 18 (13 set): | ||
+ | |||
+ | :* Uso da instrução FOR-GENERATE | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | label: FOR identificador IN faixa GENERATE | ||
+ | [Parte_Declarativa | ||
+ | BEGIN] | ||
+ | Instruções_concorrentes | ||
+ | ... | ||
+ | END GENERATE [label]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :*Exercício - Dado o somador para 4 entradas a(0) até a(3), use o FOR-GENERATE para torná-lo um somador para N entradas. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --------------------- | ||
+ | -- FILE my_pkg.vhd -- | ||
+ | --------------------- | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | |||
+ | package my_pkg is | ||
+ | type a_slv is array(natural range <>) of std_logic_vector (3 downto 0); | ||
+ | end package; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --------------------------- | ||
+ | -- FILE vector_adder.vhd -- | ||
+ | --------------------------- | ||
+ | library ieee work; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | use ieee.numeric_std.all; | ||
+ | use work.my_pkg.all; | ||
+ | |||
+ | entity vector_adder is | ||
+ | generic (N : natural := 4); | ||
+ | port ( | ||
+ | a : in a_slv (0 to N-1); | ||
+ | soma : out std_logic_vector (3 downto 0)); | ||
+ | end entity; | ||
+ | |||
+ | -- Versão que realiza a soma diretamente, mas que precisa modificar o código de acordo com o número de entradas. | ||
+ | |||
+ | architecture ifsc_v1 of vector_adder is | ||
+ | signal soma_sig : signed(3 downto 0); | ||
+ | begin | ||
+ | soma_sig <= signed(a(0)) + signed(a(1)) + signed(a(2)) + signed(a(3)); | ||
+ | soma <= std_logic_vector(soma_sig); | ||
+ | end architecture; | ||
+ | |||
+ | -- Versão que realiza a soma usando um FOR GENERATE | ||
+ | architecture ifsc_v2 of vector_adder is | ||
+ | |||
+ | begin | ||
+ | |||
+ | |||
+ | end architecture; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --------------------------- | ||
+ | -- FILE vector_adder.vhd -- | ||
+ | --------------------------- | ||
+ | configuration ifsc_cfg of vector_adder is | ||
+ | -- for ifsc_v1 end for; | ||
+ | for ifsc_v2 end for; | ||
+ | end configuration; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :*Ver pag. 127 a 134 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;Aula 19 (16 set): | ||
+ | *Código Concorrente. | ||
+ | :*Exemplo 5.3 - Unidade de Lógica e Aritmética (ALU). (Ver [https://moodle.sj.ifsc.edu.br/pluginfile.php/13347/mod_forum/attachment/3222/Captura%20de%20tela%20em%202019-09-16%2007-59-43.png?forcedownload=1 diagrama e tabela funcional no Moodle]), [https://moodle.sj.ifsc.edu.br/mod/forum/discuss.php?d=1368]. | ||
+ | |||
+ | |||
+ | ::*Fazer as seguintes alterações do código da ALU: | ||
+ | :::* Inclusão de um sinal que indica "erro" quando ocorre ''overflow''/''underflow'' nas operações de soma, incremento ou decremento. | ||
+ | :::* Inclusão de um circuito que satura o sinal no máximo positivo ou negativo nas situações de erro. | ||
+ | :::* Teste da ALU usando simulação funcional. | ||
+ | |||
+ | ;Aula 20 (18 set): | ||
+ | :*Exemplo 5.4 - Decodificador genérico de endereços. | ||
+ | |||
+ | * Implementação de conversor Binário para Gray | ||
+ | :*ver detalhes [[Código Gray]] | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity bin2gray is | ||
+ | |||
+ | generic (N : natural := 4 ) | ||
+ | |||
+ | port | ||
+ | ( | ||
+ | b : in std_logic_vector(____) | ||
+ | g : out std_logic_vector(____) | ||
+ | ) | ||
+ | |||
+ | end entity | ||
+ | |||
+ | architecture ifsc of ____ is | ||
+ | begin | ||
+ | |||
+ | |||
+ | end architecture | ||
+ | </syntaxhighlight> | ||
+ | * Implementação de conversor Gray para Binário | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity gray2bin is | ||
+ | generic (N : natural := 4 ) | ||
+ | port | ||
+ | ( | ||
+ | g : in std_logic_vector(____) | ||
+ | b : out std_logic_vector(____) | ||
+ | ) | ||
+ | end entity | ||
+ | |||
+ | architecture ifsc of ____ is | ||
+ | begin | ||
+ | |||
+ | end architecture | ||
+ | </syntaxhighlight> | ||
+ | * AE2 - Atividade Extra Classe: Implemente um circuito de incrementador Gray | ||
+ | :*Implemente um incrementador Gray, o qual dada uma entrada de N bits em código Gray fornece na saída o valor seguinte em [[Código Gray]]. | ||
+ | ::Use como base o modelo de entidade abaixo: | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity inc_gray is | ||
+ | port | ||
+ | ( | ||
+ | gray_in : in std_logic_vector(____) | ||
+ | bray_out : out std_logic_vector(____) | ||
+ | ) | ||
+ | end entity | ||
+ | |||
+ | architecture ____ of inc_gray is | ||
+ | begin | ||
+ | |||
+ | end architecture | ||
+ | </syntaxhighlight> | ||
+ | ::Por exemplo: se a entrada de 4 bits for 2 = "0011" a saída será o 3 = "0010". | ||
+ | :* Mostre que o circuito funciona, fazendo a sua simulação funcional (use o QSIM ou Modelsim). | ||
+ | :* Prazo de execução e detalhes podem ser visto na [https://moodle.sj.ifsc.edu.br/course/index.php?categoryid=177 plataforma Moodle da disciplina]. | ||
+ | |||
+ | |||
+ | ;Aula 21 (23 set): | ||
+ | * Implementação de circuitos aritméticos com operadores. | ||
+ | :* 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 a biblioteca ''numeric_std''. | ||
+ | :* 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. | ||
+ | ::*Ver a declaração das funções "+", "-", "*" e "/" no PACKAGE [[Numeric std.vhd]] | ||
+ | <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. | ||
+ | </syntaxhighlight> | ||
+ | ::* 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''. | ||
+ | |||
+ | *Exemplo 5.7 - Somador/Subtrator Recomendado. | ||
+ | :* Implementar o circuito com 4 bits na entrada e 5 bits na saída (com signed e unsigned) | ||
+ | :* Implementar o circuito com 4 bits na entrada e 4 bits na saída, e uma saída de cout para soma e para subtração | ||
+ | :* Implementar um circuito multiplicador com 4 bits na entrada e 7 bits na saída. | ||
+ | :* em todos os circuitos acima onde possa ocorrer overflow(underflow), acrescentar um circuito para saturar a saída no máximo(mínimo). | ||
+ | :* em todos os circuitos acima onde possa ocorrer overflow(underflow), acrescentar um bit de saída que indique quando o resultado está com erro. | ||
+ | |||
+ | :*Ver pag. 139 a 140 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 5 - Código Sequencial=== | ||
+ | * 7 AULAS | ||
+ | {{collapse top| Unidade 5 - Código Sequencial}} | ||
+ | |||
+ | ;Aula 23 (30 set): | ||
+ | *Código Sequencial. | ||
+ | :*Diferenças entre código concorrente e sequencial <=> circuitos combinacional e sequencial | ||
+ | :*Diferenças entre os objetos SIGNAL e VARIABLE | ||
+ | :*Tipos de elementos de memória: Latch x Flip-flop | ||
+ | ::* Latch D | ||
+ | ::* Flip-flop tipo D com reset assíncrono e com reset (clear) síncrono | ||
+ | :*Seção de código sequencial '''PROCESS''': lista de sensibilidade | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] PROCESS [(lista_de_sensibilidade)] [IS] | ||
+ | [parte_declarativa] | ||
+ | BEGIN | ||
+ | afirmação_sequencial; | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | END PROCESS [rótulo]; | ||
+ | </syntaxhighlight> | ||
+ | :*Instrução '''IF''' | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] IF condição THEN | ||
+ | afirmação_sequencial; | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | ELSIF condição THEN | ||
+ | afirmação_sequencial; | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | ELSE | ||
+ | afirmação_sequencial; | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | END IF [rótulo]; | ||
+ | </syntaxhighlight> | ||
+ | :*Exemplos: | ||
+ | ::* DFFs com Reset Assincrono e Reset Sincrono, com Enable, com Preset (Variação Ex 6.1). | ||
+ | ::* Comparar com Latch (sem clk'event). | ||
+ | ::* Simulação funcional do DFFs e do Latch | ||
+ | :*Ver pag. 161 a 160 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | |||
+ | ;Aula 24 (02 out): | ||
+ | *Código Sequencial. | ||
+ | :* Contador Básico 0-N (baseado no Ex.6.2) | ||
+ | |||
+ | |||
+ | ;Aula 25 (04 out - reposição do dia 27 set): | ||
+ | * Avaliação A1 - UN2, UN3, UN4 | ||
+ | |||
+ | ;Aula 26 (07 out): | ||
+ | *Código Sequencial. | ||
+ | :* Registrador de deslocamento (Ex.6.3) | ||
+ | ::Versão 1 - Implementação com for generate da conexão de FF D. | ||
+ | ::Versão 2 - Implementação com formação de agregado via concatenação. | ||
+ | |||
+ | ;Aula 27 (09 out) | ||
+ | |||
+ | *Código Sequencial | ||
+ | :*Instruções do tipo '''LOOP''': LOOP incondicional, FOR-LOOP, WHILE-LOOP, NEXT, EXIT | ||
+ | ::*LOOP incondicional: | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] LOOP | ||
+ | afirmação_sequencial; | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | END LOOP [rótulo]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::*FOR-LOOP: | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] FOR identificador IN faixa LOOP | ||
+ | afirmação_sequencial; | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | END LOOP [rótulo]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::*WHILE-LOOP: | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] WHILE condição LOOP -- Executa as "afirmações enquanto a "condição" for verdadeira | ||
+ | afirmação_sequencial; | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | END LOOP [rótulo]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::*LOOP com EXIT: | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] [FOR identificador IN faixa] LOOP | ||
+ | afirmação_sequencial; | ||
+ | EXIT [rótulo] [WHEN condição]; -- Se a "condição" é verdadeira, termina o "LOOP" | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | END LOOP [rótulo]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::*LOOP com NEXT: | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] [FOR identificador IN faixa] LOOP | ||
+ | afirmação_sequencial; | ||
+ | NEXT [rótulo] [WHEN condição]; -- Se a "condição" é verdadeira, não executa as linhas até a linha "END LOOP" | ||
+ | -- e incrementa o "identificador". | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | END LOOP [rótulo]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* Exemplos: | ||
+ | ::* Carry-Ripple Adder (FOR-LOOP) (Ex 6.4) - apenas analisar | ||
+ | ::* Leading Zeros (LOOP com EXIT) (Ex 6.5) - obter ocódigo no Moodle; fazer a síntese do circuito; fazer simulação no Modelsim; analisar a forma como o compilador implementou o incrementador. | ||
+ | :*Ver pag. 161 a 164 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;Aula 28 (11 out): | ||
+ | :*Instrução '''CASE''' | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] CASE expressão IS | ||
+ | WHEN valor => atribuições; -- valor único | ||
+ | ... | ||
+ | WHEN valor1 | valor2 | ... | valorN => atribuições; -- lista de valores | ||
+ | ... | ||
+ | WHEN valor1 TO valor2 => atribuições; -- faixa de valores | ||
+ | ... | ||
+ | |||
+ | END CASE; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :*Instrução '''WAIT''': WAIT UNTIL, WAIT FOR (simulação apenas), WAIT ON (não implementada no Quartus II). | ||
+ | ::Recomenda-se utilizar a lista de sensibilidade do PROCESS e a instrução IF no lugar do WAIT. | ||
+ | ::Algumas instruções de '''WAIT''' serão utilizadas na criação de '''TestBench''' em VHDL para a simulação com o '''MODELSIM'''. | ||
+ | |||
+ | :* Timer de 0 a 9 segundos com saída SSD (Ex 6.6). | ||
+ | ::* Unir o código de um contador de 0 a 9 (código sequencial), e um conversor de binário para sete segmentos em código sequencial (usando CASE). | ||
+ | ::* Depois acrescentar um circuito que permita obter um clock com período de 1 segundo, a partir de um sinal de clock com frequência de fclk = 50MHz. | ||
+ | ::* Implementar no FPGA o circuito com contador de 0 a 9 segundos com saída SSD e clk de entrada de 50MHz. | ||
+ | :::*PROBLEMA: Uso de um período de clock de 20 ns => 50 MHz, verificar a impossibilidade prática de uma simulação deste circuito (1 segundo => 5 minutos de simulação), devido ao tamanho do contador (count1) que conta de 0 a 50M-1. | ||
+ | :::*SOLUÇÃO: modificar o contador para um valor máximo menor (0 a 50-1). Notar que a simulação é extremamente rápida neste caso. | ||
+ | :::*Após verificar que o circuito funciona "simulado", configurar o FPGA do kit Mercúrio IV para implementar este circuito. As informações necessárias estão em [[Preparando para gravar o circuito lógico no FPGA]]. Utilize os pinos (clk = CLOCK_50MHz: PIN_T1, led = DISP0_D[7] : PIN_W1, ssd = DISP0_D[0-6]: PIN_V2 - PIN_W2). | ||
+ | :::* Como o conversor de binário para ssd realizado anteriormente tinha lógica negativa ('0' acende, '1' apaga), será necessário inverter todas as saídas | ||
+ | ssd_out <= not ssd; | ||
+ | :::*Se quiser usar um led na matriz de led é necessário colocar '0' da coluna do Led e '1' na linha correspondente, ou seja utilizar um segundo pino para acender o led. | ||
+ | |||
+ | ;Aula 29 (14 out): | ||
+ | *Uso do Modelsim para simulação funcional. | ||
+ | :*Use o Modelsim para fazer a simulação do circuito do timer de 0 a 9 segundos. | ||
+ | :*Ver [[Seguindo o tutorial da ALTERA para o MODELSIM]], para utilizar o básico do MODELSIM. | ||
+ | :* [http://www.vhdl.us/Book_VHDL_2ed_unrestricted/Pedroni_VHDL_2ed_tutorial_ModelSim_10.1d_v2.pdf Pedroni VHDL 2ed Tutorial of ModelSim 10.1d] | ||
+ | :* [https://www.youtube.com/watch?v=Z8whdGa7RtY ModelSim Video Tutorial] - Kirk Weedman | ||
+ | :*[[Media:modelsim_tut.pdf |ModelSim® Tutorial]] -v10.0d | ||
+ | :* [[Documentação do ModelSim]], para conhecer mais a fundo o MODELSIM. | ||
+ | |||
+ | <!-- | ||
+ | *Projete um contador BCD de 00 a 99 configurável. | ||
+ | ::Efetue a simulação funcional (Usando o QSIM e o Modelsim) fazendo a contagem de 00 a 11 e 00 a 23 (para hora) , de 00 a 59 (para minutos e segundos), e de 00 a 99. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity Count00_99 is | ||
+ | port ( | ||
+ | clk : in std_logic; | ||
+ | bcd_U : out std_logic_vector(3 downto 0); | ||
+ | bcd_D : out std_logic_vector(3 downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Implementação de um relógio contador BCD de segundos. | ||
+ | :*Utilizando o sistema anterior, inclua um contador em BCD de dois dígitos que permita fazer a contagem de 00 a 99, onde o valor final é configurável. | ||
+ | ::Efetue a simulação funcional (Usando o QSIM e o Modelsim) fazendo a contagem de 00 a 11 e 00 a 23 (para hora) , de 00 a 59 (para minutos e segundos), e de 00 a 99. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity Timer00_99seg is | ||
+ | port ( | ||
+ | clk50MHz : in std_logic; | ||
+ | clk1seg : out std_logic; | ||
+ | SSD_Useg : out std_logic_vector(0 to 6); | ||
+ | SSD_Dseg : out std_logic_vector(0 to 6) | ||
+ | ); | ||
+ | end entity; | ||
+ | </syntaxhighlight> | ||
+ | ::configure o FPGA do kit Mercúrio IV para implementar este circuito. Utilize os mostradores ssd DISP0_D e DISP1_D. | ||
+ | *Projeto e simulação com Modelsim do sistema Timer00-99 com display de 7 segmentos e divisor de clock. | ||
+ | *Na simulação definir o clk50MHz como 100ms para produzir um clk1sec com duração de 1 segundo. | ||
+ | *Corrigir o primeiro período de clock de clk1sec. É necessário fazer com que o sinal seja alto primeiro e depois vá para baixo de modo a garantir que a transição positiva ocorra depois de 1 segundo. | ||
+ | *'''IMPORTANTE''': Também é necessário incluir um RESET em cada circuito que seja sequencial. Também é necessário iniciar o circuito com um reset de 10 ps na simulação. | ||
+ | *Perceber a necessidade de parametrizar o conversor de bcd2ssd para permitir displays do tipo CA e AA. (ler [[Display de 7 segmentos]]) | ||
+ | *Perceber a necessidade de incluir um sinal que indique o final da contagem no counter00_99. Esse sinal poderá ser usado como clock no relógio a ser projetado. | ||
+ | --> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 6 - Projeto a nível de Sistema=== | ||
+ | * 8 AULAS | ||
+ | {{collapse top| Unidade 6 - Projeto a nível de Sistema}} | ||
+ | |||
+ | ; Aula 30 e 31 (16 e 21 out): | ||
+ | *Projeto a nível de Sistema. | ||
+ | :* O '''PACKAGE''' e '''PACKAGE BODY''': onde declarar e como usar. | ||
+ | :* O '''COMPONENT''': declaração (cópia da '''ENTITY''') e instanciação. | ||
+ | Assim a entity Timer00_99 | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ENTITY timer00_99seg | ||
+ | GENERIC (D : INTEGER; | ||
+ | fclock : INTEGER; | ||
+ | U : INTEGER); | ||
+ | PORT (clk50MHz : IN STD_LOGIC; | ||
+ | RST : IN STD_LOGIC; | ||
+ | clk1seg : OUT STD_LOGIC; | ||
+ | SSD_Dseg : OUT STD_LOGIC_VECTOR(0 TO 6); | ||
+ | SSD_Useg : OUT STD_LOGIC_VECTOR(0 TO 6)); | ||
+ | END ENTITY; | ||
+ | </syntaxhighlight> | ||
+ | Será declarada como um COMPONENT | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | COMPONENT timer00_99seg | ||
+ | GENERIC (D : INTEGER; | ||
+ | fclock : INTEGER; | ||
+ | U : INTEGER); | ||
+ | PORT (clk50MHz : IN STD_LOGIC; | ||
+ | RST : IN STD_LOGIC; | ||
+ | clk1seg : OUT STD_LOGIC; | ||
+ | SSD_Dseg : OUT STD_LOGIC_VECTOR(0 TO 6); | ||
+ | SSD_Useg : OUT STD_LOGIC_VECTOR(0 TO 6)); | ||
+ | END COMPONENT; | ||
+ | </syntaxhighlight> | ||
+ | ::* Associação dos nomes das portas aos sinais. PORT -> '''PORT MAP''': | ||
+ | ::* Mapeamento por posição e nominal. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | comp1 : timer00_99seg | ||
+ | GENERIC MAP (2, 10, 3) | ||
+ | PORT MAP (clk50MHz,RST, clk1seg, SSD_Dseg, SSD_Useg); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | comp1 : timer00_99seg | ||
+ | GENERIC MAP ( D => 2, U => 3, | ||
+ | fclock => 10, | ||
+ | PORT MAP ( clk50MHz => clk50MHz, | ||
+ | RST => RST, | ||
+ | clk1seg => clk1seg, | ||
+ | SSD_Dseg => SSD_Dseg, | ||
+ | SSD_Useg => SSD_Useg); | ||
+ | </syntaxhighlight> | ||
+ | ::* Métodos de declaração de '''COMPONENT'''. | ||
+ | :::*Exemplo: Registrador Circular Ex. 8.2 | ||
+ | :* Criação de '''COMPONENT''' redimensionáveis. GENERIC -> '''GENERIC MAP''' | ||
+ | ::*Exemplo: Porta E com N entradas. | ||
+ | ::*Exemplo: Detector de Paridade Ex. 8.3 | ||
+ | :* Ver pag. 201 a 213 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | |||
+ | ; Aula 32-33 (24-25 out): | ||
+ | :* Instanciação de '''COMPONENT''' com '''GENERATE'''. | ||
+ | |||
+ | :* Uso da instrução '''CONFIGURATION'''. | ||
+ | ::* Ligação direta: ARCHITECTURE-ENTITY. | ||
+ | ::* Ligação da instanciação dos componentes: COMPONENT-ENTITY(ARCHITECTURE). | ||
+ | |||
+ | * Implementação de um timer de 99 segundos usando componentes. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity timer00_99seg IS | ||
+ | generic (fclk2 : natural := 50, D : natural := 5; U : natural := 9); | ||
+ | port | ||
+ | ( | ||
+ | clk50MHz : in STD_LOGIC; | ||
+ | clk_1seg: out STD_LOGIC; | ||
+ | ssd_D : out STD_LOGIC_VECTOR(0 TO 6); | ||
+ | ssd_U : out STD_LOGIC_VECTOR(0 TO 6) | ||
+ | ); | ||
+ | end entity; | ||
+ | </syntaxhighlight> | ||
+ | ;OBS: | ||
+ | *O valor do fclk2 corresponde a metade do período do clock de entrada em Hz. | ||
+ | *Os valores D e U correspondem ao último valor do timer, depois desse valor o timer dever reiniciar a contagem. | ||
+ | |||
+ | : Componente 1 - Divisor de Clock, con o valor da divisão configurável pelo parâmetro '''fclk2''' | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | component div_clk is | ||
+ | generic (fclk2 : natural := 50); -- frequecia para simulacao | ||
+ | port ( | ||
+ | clk : in std_logic; | ||
+ | clk_out : out std_logic | ||
+ | ); | ||
+ | end component; | ||
+ | ;OBS: | ||
+ | *O valor do fclk2 corresponde a metade do período do clock de entrada em Hz. | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | : Componente 2 - Contador de 00 a 99 com saída em BCD, com o valor final configurável pelos parâmetros '''D e U''' | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | component count00_99 is | ||
+ | generic (D : natural := 9; U : natural := 9); | ||
+ | port ( | ||
+ | clk : in std_logic; | ||
+ | clk_out : out std_logic; | ||
+ | bcd_U : out std_logic_vector(3 downto 0); | ||
+ | bcd_D : out std_logic_vector(3 downto 0) | ||
+ | ); | ||
+ | end component; | ||
+ | </syntaxhighlight> | ||
+ | ;OBS: | ||
+ | *Os valores D e U correspondem ao último valor do timer, depois desse valor o timer dever reiniciar a contagem. | ||
+ | |||
+ | : Componente 3 - Conversor de BIN para SSD, com um parâmetro configurável '''ac_ccn''' para selecionar Anodo ou Catodo Comum. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | component bin2ssd is | ||
+ | generic (ac_ccn : natural := 0); | ||
+ | port ( | ||
+ | bin_in : in std_logic_vector(3 downto 0); | ||
+ | ssd_out : out std_logic_vector(0 to 6) | ||
+ | ); | ||
+ | end component; | ||
+ | </syntaxhighlight> | ||
+ | ;OBS: | ||
+ | *O valor ac_ccn é utilizado para configurar o circuito entre ativo alto para display de catodo comum (ac_ccn=0), ou ativo baixo para display de anodo comum (ac_ccn=1). | ||
+ | |||
+ | |||
+ | O timer deve utilizar os componentes acima de modo a resultar em um RTL semelhante ao mostrado abaixo. | ||
+ | <center> | ||
+ | [[Arquivo:rtl_timer99sec.png | 600 px]] | ||
+ | </center> | ||
+ | * Simulação do timer com ModelSim. Na simulação definir o clk50MHz com duração de 10 ms. Faça uma simulação de pelo menos 60 segundos. | ||
+ | |||
+ | <center> | ||
+ | [[Arquivo:sim_timer99sec.png | 800 px]] | ||
+ | </center> | ||
+ | OBS: É recomendável inserir um sinal de RESET em todos os circuitos sequenciais e ao iniciar a simulação do circuito começar com RESET ativo durante 10 ps. | ||
+ | |||
+ | *Após verificar que a simulação do circuito está funcionando, configurar um FPGA para implementar este circuito. Existem duas opções de kit disponíveis com displays de sete segmentos. As informações necessárias estão em [[Preparando para gravar o circuito lógico no FPGA]]. | ||
+ | :* Ao utilizar o kit DE2-115 da TERASIC, utilize os pinos (clk = CLOCK_50: PIN_Y2, rst = KEY[0]: PIN_M23, ssd = HEX0-5[0-6]: PIN_G18 - PIN_H22 ...). | ||
+ | {{collapse top| definição dos pinos}} | ||
+ | <code> | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | :*Ao utilizar o kit Mercúrio IV da MACNICA, utilize os pinos (clk = CLOCK_50MHz: PIN_T1, led = DISP0_D[7] : PIN_W1, ssd = DISP0_D[0-6]: PIN_V2 - PIN_W2). | ||
+ | {{collapse top| definição dos pinos}} | ||
+ | <code> | ||
+ | set_location_assignment PIN_T1 -to clk50MHz | ||
+ | set_location_assignment PIN_V21 -to rst_in | ||
+ | set_location_assignment PIN_R5 -to ssd_D[0] | ||
+ | set_location_assignment PIN_T5 -to ssd_D[1] | ||
+ | set_location_assignment PIN_T3 -to ssd_D[2] | ||
+ | set_location_assignment PIN_T4 -to ssd_D[3] | ||
+ | set_location_assignment PIN_M6 -to ssd_D[4] | ||
+ | set_location_assignment PIN_N7 -to ssd_D[5] | ||
+ | set_location_assignment PIN_N6 -to ssd_D[6] | ||
+ | set_location_assignment PIN_V2 -to ssd_U[0] | ||
+ | set_location_assignment PIN_V1 -to ssd_U[1] | ||
+ | set_location_assignment PIN_U2 -to ssd_U[2] | ||
+ | set_location_assignment PIN_U1 -to ssd_U[3] | ||
+ | set_location_assignment PIN_Y2 -to ssd_U[4] | ||
+ | set_location_assignment PIN_Y1 -to ssd_U[5] | ||
+ | set_location_assignment PIN_W2 -to ssd_U[6] | ||
+ | set_location_assignment PIN_W1 -to clk_1seg | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | :* Análise o diagrama esquemático como funcionam as chaves e também o tipo de display. Note que no projeto o signal RST foi descrito como normalmente ALTO, podendo ser necessário acrescentar um inversor para ter o funcionamento correto. O [[Display de 7 segmentos]] da DE2-115 é do tipo cátodo comum, enquanto que na MERCURIO IV ele é do tipo ânodo comum. | ||
+ | |||
+ | <!-- | ||
+ | ; Aula 36 (31 Out): | ||
+ | *Projeto a nível de Sistema. | ||
+ | FUNCTION e PROCEDURE (são chamados de subprogramas), e podem ser construídos em um PACKAGE, ENTITY, ARCHITECTURE, ou PROCESS. | ||
+ | |||
+ | A instrução '''ASSERT''' é útil para verificar as entradas de um subprograma. Seu propósito não é criar circuito, mas assegurar que certos requisitos são atendidos durante a sintese e/ou simulação. Pode ser condicional ou incondicional (condição_booleana = FALSE). A sintaxe da instrução é: | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] assert condição_booleana | ||
+ | [report mensagem] | ||
+ | [severity nivel_severidade]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A mensagem pode ser criada usando STRINGs que podem ser concatenadas. | ||
+ | |||
+ | O nível de severidade pode ser NOTE (para passar informação para o compilador/simulator), WARNING (para informar que algo não usual ocorreu), ERROR (para informar que alguma condição não usual "sério" ocorreu), ou FAILURE (para informar que uma condição não aceitável ocorreu). Normalmente o compilador para quando ocorre um ERROR ou FAILURE. ERROR é o valor "default" [https://www.ics.uci.edu/~jmoorkan/vhdlref/assert.html]. | ||
+ | |||
+ | :* A '''FUNCTION''': declaração, uso, mapeamento posicional x nominal, PURE x IMPURE. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | function nome_funçao (lista_parametros_entrada) return tipo_saida is | ||
+ | declarações | ||
+ | begin | ||
+ | afirmações sequenciais | ||
+ | end function; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* Uso de '''FUNCTION''' e '''ASSERT'''. | ||
+ | ::* Exemplo: Declaração em ARCHITECTURE Ex.9.1 | ||
+ | ::* Exemplo: Declaração em PACKAGE Ex. 9.2 | ||
+ | ::* Exemplo: Declaração em ENTITY Ex. 9.3 | ||
+ | |||
+ | Abaixo segue um exemplo de cálculo do '''log2''' de um número inteiro. Pode ser usado para determinar o número de bits necessário para um número natural. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | function log2c (n : integer) return integer is | ||
+ | variable m , p : integer; | ||
+ | begin | ||
+ | m := 0; | ||
+ | p : = 1; | ||
+ | while p < n loop | ||
+ | m : = m + 1; | ||
+ | p := p * 2; | ||
+ | end loop; | ||
+ | return m; | ||
+ | end log2c; | ||
+ | </syntaxhighlight> | ||
+ | --> | ||
+ | <!-- | ||
+ | ; Aula 37 (19 mai): | ||
+ | :*Uso de '''PROCEDURE'''. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | procedure nome_procedimento (lista_parâmetros_entrada, lista_parâmetros_saída) is | ||
+ | declarações | ||
+ | begin | ||
+ | afirmações sequenciais | ||
+ | end procedure; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::*Exemplo: min_max Ex.9.4 | ||
+ | ::*Exercícios: 9.1 a 9.4, 9.6 a 9.9 | ||
+ | :* Ver pag. 213 a 239 de <ref name="PEDRONI2010b"/>) | ||
+ | |||
+ | ; Aula 33 e 34 (23 e 26 mai): | ||
+ | :*Uso de '''FUNCTION''' e '''PROCEDURE'''. | ||
+ | ::*Exercícios: 9.1 a 9.4, 9.6 a 9.9 | ||
+ | |||
+ | ;Aula 36 a 38 (4 a 8 jun): | ||
+ | * Implementação de um serializador e um deserializador usando componentes. | ||
+ | : Componente 1 - Divisor de Clock, con o valor da divisão configurável pelo '''generic N''' | ||
+ | entity div_clk is | ||
+ | entrada clk_in | ||
+ | saída clk_out | ||
+ | : Componente 2 - Registrador de deslocamento com entrada serial e paralelo e saída serial e paralelo com N FF, configurável pelo '''generic N''' | ||
+ | entity shift_reg is | ||
+ | entradas clk_in, rst_in, ena_in, d_in[N-1..0], s_in | ||
+ | saídas d_out[N-1..0], s_out | ||
+ | |||
+ | : Componente 3 - Porta paralela com N entradas, configurável pelo '''generic N'''. | ||
+ | entity port_par is | ||
+ | entradas clk_in, rst, ena, d_in[N-1..0] | ||
+ | saídas d_out[N-1..0] | ||
+ | |||
+ | * Simulação do serializador e deserializador com ModelSim. | ||
+ | * Integração dos dois componentes em um único componente. | ||
+ | |||
+ | ;Aula 27 (7 mai): | ||
+ | * Implementar um circuito de relógio que conte HH:MM:SS. | ||
+ | |||
+ | :::*PROBLEMA: Uso de um período de clock de 20 ns => 50 MHz, verificar a impossibilidade prática de uma simulação deste circuito (1 segundo => 5 minutos de simulação), devido ao tamanho do contador (count1) que conta de 0 a 50M-1. | ||
+ | :::*SOLUÇÃO: modificar o contador para um valor maximo menor (0 a 5-1), e a mesmo tempo mudar o período de clock para 200 ms => 5 Hz. Notar que a simulação é extremamente rápida neste caso. | ||
+ | :::*Após verificar que o circuito funciona "simulado", configurar o FPGA do kit DE2-115 para implementar este circuito. As informações necessárias estão em [[Preparando para gravar o circuito lógico no FPGA]]. Utilize os pinos (clk = CLOCK_50: PIN_Y2, rst = KEY[0]: PIN_M23, ssd = HEX0[0-6]: PIN_G18 - PIN_H22). Note que a chave usada para o rst é normalmente alta, e portanto é necessário acrescentar um inversor a esta entrada. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- Renomeie a porta rst para rst_in. | ||
+ | PORT ( | ||
+ | clk, rst_in : IN BIT; | ||
+ | |||
+ | --Crie um sinal interno para inverter o clock | ||
+ | ARCHITECTURE counter OF slow_counter IS | ||
+ | signal rst : BIT; | ||
+ | BEGIN | ||
+ | rst <= not rst_in; | ||
+ | </syntaxhighlight> | ||
+ | :::*Programe o FPGA usando o programador e verifique se a contagem está correta (a cada segundo). | ||
+ | |||
+ | ;Aula 29,30 ( ): | ||
+ | *Código Sequencial. | ||
+ | * Projeto de relógio HH:MM:SS com conversor para 7 segmentos. Implementar um relógio usando um COMPONENT contador BCD de 00 a 99. Instancie 3 COMPONENTES para implementar a hora, o minuto e o segundo. O relógio deve contar de 00:00:00 até 23:59:59. Os mostradores de 7 segmentos devem ser implementados com um COMPONENT "bin2ssd" que converte o número 0 a 9 em bits do código SSD. | ||
+ | :* Simular o relógio HH:MM:SS com Modelsim, duração de 49 horas. | ||
+ | :* Implementar o relógio no kit DE2-115 (opcional) - neste caso é necessário incluir um divisor de clock antes do contador de segundo. | ||
+ | |||
+ | ::*Exercício 28.1: Inserir as duas soluções de ARCHITECTURE do exercício EX 6.10 (Timer de dois digitos) em uma única ENTITY. Utilizar CONFIGURATION para fazer a ligação com a arquitetura desejada. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity counter60seg is | ||
+ | generic (fclk: integer := 2); -- valor usado para simulação. | ||
+ | -- generic (fclk: integer := 50_000_000); -- valor usado para implementação com clk de 50 MHz. | ||
+ | port ( | ||
+ | clk, rst : in std_logic; | ||
+ | ssd_un, ssd_dz: out std_logic_vector(6 downto 0)); | ||
+ | end entity ; | ||
+ | |||
+ | architecture version1 of counter60seg is | ||
+ | -- Versão proposta por Gabriel Cantu (processo único) | ||
+ | ... | ||
+ | begin | ||
+ | ... | ||
+ | end architecture ; | ||
+ | |||
+ | architecture version2 of counter60seg is | ||
+ | -- Versão proposta por Gustavo Constante (5 processos) | ||
+ | ... | ||
+ | begin | ||
+ | ... | ||
+ | end architecture ; | ||
+ | |||
+ | configuration counter60seg_cfg of counter60seg is | ||
+ | for version1 end for; | ||
+ | -- for version2 end for; | ||
+ | end configuration; | ||
+ | </syntaxhighlight> | ||
+ | --> | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 7 - Maquinas de Estado Finitas=== | ||
+ | {{collapse top| Unidade 7 - Maquinas de Estado Finitas}} | ||
+ | * 6 AULAS | ||
+ | |||
+ | ; Aula 34 (30 out): | ||
+ | *Introdução ao Projeto de Maquinas de Estado Finitas (FSM) em VHDL | ||
+ | :* O que é uma FSM - Finite State Machine | ||
+ | :* Modelo de FSM | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | LIBRARY ieee; | ||
+ | USE ieee.std_logic_1164.ALL; | ||
+ | ---------------------------------------------------------- | ||
+ | ENTITY < entity_name > IS | ||
+ | PORT ( | ||
+ | clk, rst : IN STD_LOGIC; | ||
+ | input : IN < data_type > ; | ||
+ | output : OUT < data_type >); | ||
+ | END < entity_name > ; | ||
+ | ---------------------------------------------------------- | ||
+ | ARCHITECTURE < architecture_name > OF < entity_name > IS | ||
+ | TYPE state IS (A, B, C, ...); | ||
+ | SIGNAL pr_state, nx_state : state; | ||
+ | ATTRIBUTE ENUM_ENCODING : STRING; --optional attribute | ||
+ | ATTRIBUTE ENUM_ENCODING OF state : TYPE IS "sequential"; | ||
+ | BEGIN | ||
+ | ------Logica Sequencial da FSM:------------ | ||
+ | PROCESS (clk, rst) | ||
+ | BEGIN | ||
+ | IF (rst = '1') THEN | ||
+ | pr_state <= A; | ||
+ | ELSIF (clk'EVENT AND clk = '1') THEN | ||
+ | pr_state <= nx_state; | ||
+ | END IF; | ||
+ | END PROCESS; | ||
+ | ------Logica Combinacional da FSM:------------ | ||
+ | PROCESS (pr_state, input) | ||
+ | BEGIN | ||
+ | ------Valores default das saidas------------ | ||
+ | output <= < value > ; | ||
+ | CASE pr_state IS | ||
+ | WHEN A => | ||
+ | output <= < value > ; -- apenas se diferente do valor default | ||
+ | IF (input =< value >) THEN | ||
+ | nx_state <= B; | ||
+ | ... | ||
+ | ELSE | ||
+ | nx_state <= A; | ||
+ | END IF; | ||
+ | WHEN B => | ||
+ | output <= < value > ; -- apenas se diferente do valor default | ||
+ | IF (input =< value >) THEN | ||
+ | nx_state <= C; | ||
+ | ... | ||
+ | ELSE | ||
+ | nx_state <= B; | ||
+ | END IF; | ||
+ | WHEN ... | ||
+ | END CASE; | ||
+ | END PROCESS; | ||
+ | ------Seção de Saída (opcional):------- | ||
+ | PROCESS (clk, rst) | ||
+ | BEGIN | ||
+ | IF (rst = '1') THEN | ||
+ | new_output <= < value > ; | ||
+ | ELSIF (clk'EVENT AND clk = '1') THEN --or clk='0' | ||
+ | new_output <= output; | ||
+ | END IF; | ||
+ | END PROCESS; | ||
+ | END < architecture_name > ; | ||
+ | </syntaxhighlight> | ||
+ | :* Usando o template acima descreva em VHDL a FSM indicada na Figura 11.1. | ||
+ | :* Faça a simulação da FSM com Modelsim utilizando um testbench em VHDL que faça a FSM seguir os estados | ||
+ | :rst -> A -(x=0)-> A -(x=1)-> A -(x=2)-> B -(x=2)-> B -(x=0)-> C -(x=0)-> C -(x=2)-> C -(x=1)-> A -(x=2)-> B -(x=1)-> A. | ||
+ | :: Ver pag. 277 a 35 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ; Aula 35 (04 nov): | ||
+ | *Introdução ao Projeto de Maquinas de Estado Finitas (FSM) em VHDL | ||
+ | :* Exemplo 11.1 Controlador de uma máquina de Venda | ||
+ | ::*Compile o código mostrado no Exemplo 11.1. | ||
+ | ::*Simule a FSM com Modelsim utilizando um testbench em VHDL para gerar o teste mostrado na figura abaixo. | ||
+ | |||
+ | :::[[Arquivo:FSM_tb40.png | 1000 px]] | ||
+ | |||
+ | :* Exercício: Altere a FSM para vender doces que custam 30 centavos. Considere que as moedas aceitas são 5, 10, 25 e 50 centavos. Desenho primeiro a FSM e em seguida implemente-a em VHDL e faça a simulação. | ||
+ | :: Ver pag. 281 a 282 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | |||
+ | ; Aula 36 (06 nov) | ||
+ | *Introdução ao Projeto de Maquinas de Estado Finitas (FSM) em VHDL | ||
+ | :* O problema de bypassar estados em FSM (explicação do funcionamento através do alarme de carro. | ||
+ | ::* Exemplo 11.4 Alarme de Carro (com FLAG) | ||
+ | ::* Exemplo 11.5 Alarme de Carro (com estados de WAIT adicionais). | ||
+ | :: Ver pag. 292 a 297 de <ref name="PEDRONI2010b"/> | ||
+ | :* Projeto de FSM temporizadas (nas quais as transições são ativadas também pelo tempo). | ||
+ | :* Modelo de FSM temporizada | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | LIBRARY ieee; | ||
+ | USE ieee.std_logic_1164.ALL; | ||
+ | ---------------------------------------------------------- | ||
+ | ENTITY < entity_name > IS | ||
+ | PORT ( | ||
+ | clk, rst : IN STD_LOGIC; | ||
+ | input : IN < data_type > ; | ||
+ | output : OUT < data_type >); | ||
+ | END < entity_name > ; | ||
+ | ---------------------------------------------------------- | ||
+ | ARCHITECTURE < architecture_name > OF < entity_name > IS | ||
+ | TYPE state IS (A, B, C, ...); | ||
+ | SIGNAL pr_state, nx_state : state; | ||
+ | signal timer: integer range 0 to MAX; | ||
+ | -- ATTRIBUTE ENUM_ENCODING : STRING; --optional attribute | ||
+ | -- ATTRIBUTE ENUM_ENCODING OF state : TYPE IS "sequential"; | ||
+ | BEGIN | ||
+ | ------Logica Sequencial da FSM:------------ | ||
+ | PROCESS (clk, rst) | ||
+ | variable count: integer range o to MAX; | ||
+ | BEGIN | ||
+ | IF (rst = '1') THEN | ||
+ | pr_state <= A; | ||
+ | count := 0; | ||
+ | ELSIF (clk'EVENT AND clk = '1') THEN | ||
+ | count := count + 1; | ||
+ | if (count >= timer) then | ||
+ | pr_state <= nx_state; | ||
+ | count := 0; | ||
+ | end if; | ||
+ | END IF; | ||
+ | END PROCESS; | ||
+ | ------Logica Combinacional da FSM:------------ | ||
+ | PROCESS (pr_state, input) | ||
+ | BEGIN | ||
+ | ------Valores default das saidas------------ | ||
+ | output <= < value >; | ||
+ | ------Valores default do timer------------ | ||
+ | timer <= <value>; | ||
+ | CASE pr_state IS | ||
+ | WHEN A => | ||
+ | output <= < value > ; -- apenas se diferente do valor default | ||
+ | IF (input =< value >) THEN | ||
+ | timer <= <value>; -- apenas se diferente do valor default | ||
+ | nx_state <= B; | ||
+ | ... | ||
+ | ELSE | ||
+ | timer <= <value>; -- apenas se diferente do valor default | ||
+ | nx_state <= A; | ||
+ | END IF; | ||
+ | WHEN B => | ||
+ | output <= < value > ; -- apenas se diferente do valor default | ||
+ | IF (input =< value >) THEN | ||
+ | timer <= <value>; -- apenas se diferente do valor default | ||
+ | nx_state <= C; | ||
+ | ... | ||
+ | ELSE | ||
+ | timer <= <value>; -- apenas se diferente do valor default | ||
+ | nx_state <= B; | ||
+ | END IF; | ||
+ | WHEN ... | ||
+ | END CASE; | ||
+ | END PROCESS; | ||
+ | ------Seção de Saída (opcional):------- | ||
+ | PROCESS (clk, rst) | ||
+ | BEGIN | ||
+ | IF (rst = '1') THEN | ||
+ | new_output <= < value > ; | ||
+ | ELSIF (clk'EVENT AND clk = '1') THEN --or clk='0' | ||
+ | new_output <= output; | ||
+ | END IF; | ||
+ | END PROCESS; | ||
+ | END < architecture_name > ; | ||
+ | </syntaxhighlight> | ||
+ | :: Ver pag. 298 a 301 de <ref name="PEDRONI2010b"/> | ||
+ | :* Usando o template acima descreva em VHDL a FSM de um controlador de semáforo Regular da Figura 11.15 (pag. 304 de <ref name="PEDRONI2010b"/>). | ||
+ | <center> | ||
+ | [[Arquivo:Semaforo_FSM.png| 800px]] | ||
+ | </center> | ||
+ | ::* Para definir as temporizações utilize GENERICs que permitam instanciar diferentes semáforos em um projeto de controle de tráfego de uma avenida. | ||
+ | ::* Considere que o sinal de clock tem período de 1 segundo. | ||
+ | ::* Realize a simulação do semáforo, destacando as saídas com as cores correspondentes, conforme mostrado abaixo: | ||
+ | <center> | ||
+ | [[Arquivo:Semaforo_ModelSim.png| 800px]] | ||
+ | </center> | ||
+ | |||
+ | |||
+ | ; Aula 37 (08 nov) | ||
+ | *Exercício: Faça o download do arquivo simple_car_alarm.qar, disponível no Moodle da disciplina e realize as seguintes avaliações: | ||
+ | :#Perceba que existem 4 versões para o mesmo Alarme de Carro. Realize a simulação no ModelSim das 4 versões e perceba qual é a diferença de funcionamento desses circuitos. | ||
+ | :#Anote o número de elementos em cada versão. | ||
+ | :#Qual versão é a mais adequada na sua opinião? | ||
+ | :#Modifique a sua escolha para que o alarme não possa ser ativado se o "sensor" estiver em "1". | ||
+ | :#Analise o arquivo tb_vX.do e modifique-o para testar também essa nova condição. A simulação deve obrigatoriamente fazer o sistema passar por todos os estados e todas as transições. | ||
+ | :#Implemente a nova versão como uma nova arquitetura "fsm_v5", e escrever o arquivo de simulação "tbv5.do". | ||
+ | :#Salve as telas da simulação ("v5_sim.png"), tela da fsm ("v5_fsm.png"), tela do RTL ("v5_rtl.png"). | ||
+ | :#Acrescente os novos arquivos no projeto e salve o novo .qar | ||
+ | |||
+ | <!-- | ||
+ | ; Aula 37 (08 nov) | ||
+ | *Introdução ao Projeto de Maquinas de Estado Finitas (FSM) em VHDL | ||
+ | :* Maquina FSM . | ||
+ | :*Implementar a FSM para uma sinaleira manual para duas vias. A mudança do sinal deve ser feito a partir do acionamento de uma chave por um guarda. | ||
+ | <code> | ||
+ | ENTITY sinal_manual IS | ||
+ | PORT ( | ||
+ | clk, rst : IN STD_LOGIC; | ||
+ | guarda: IN STD_LOGIC; | ||
+ | LVd1, LAm1, LVm1 : OUT std_logic; -- Lampadas da Via 1 | ||
+ | LVd2, LAm2, LVm2 : OUT std_logic -- Lampadas da Via 2 | ||
+ | ); | ||
+ | END entity ; | ||
+ | </syntaxhighlight> | ||
+ | O diagrama da FSM deve ser algo parecido com o mostrado abaixo | ||
+ | <center> | ||
+ | [[Arquivo:FSMSinaleiraManual.png|800px]] | ||
+ | </center> | ||
+ | *Note que se o sinal guarda permanece alto por mais que um clock, ocorre a mudança de mais de um estado. Para evitar esse problema pode ser utilizada a técnica de usar um FLAG, ou estados de WAIT no qual se aguarda o retorno dos sinal para baixo antes de avançar para o próximo estado. | ||
+ | |||
+ | |||
+ | ; Aula 39 (mai): | ||
+ | *Introdução ao Projeto de Maquinas de Estado Finitas (FSM) em VHDL | ||
+ | :* Maquina FSM temporizada. | ||
+ | :*Implementar a maquina temporizada para uma sinaleira automática para duas vias. | ||
+ | <code> | ||
+ | ENTITY sinal_auto IS | ||
+ | GENERIC (TVd1: natural := 300; TVd2: natural := 120; TAm: natural := 10); | ||
+ | PORT ( | ||
+ | clk, rst : IN STD_LOGIC; | ||
+ | LVd1, LAm1, LVm1 : OUT std_logic; -- Lampadas da Via 1 | ||
+ | LVd2, LAm2, LVm2 : OUT std_logic -- Lampadas da Via 2 | ||
+ | ); | ||
+ | END entity ; | ||
+ | </syntaxhighlight> | ||
+ | Os tempos '''TVd1''' e '''TVd2''' são os tempos em segundos para verde das vias 1 e 2 respectivamente. '''TAm''' é o tempo em segundos que fica em amarelo em ambas vias. | ||
+ | |||
+ | A simulação no ModelSim da sinaleira deve resultar em algo conforme mostrado abaixo: | ||
+ | <center> | ||
+ | [[Arquivo:SimSinaleiraAutom.png|800px]] | ||
+ | </center> | ||
+ | |||
+ | *'''DICA:''' Use na simulação comandos que automatizam o processo através de um script '''tb_sinal_auto.do''' | ||
+ | <code> | ||
+ | vcom -93 -work work {../../sinal_auto.vhd} | ||
+ | vsim work.sinal_auto | ||
+ | do wave.do | ||
+ | force -freeze sim:/sinal_auto/clk 1 0, 0 {0.5sec} -r {1 sec} | ||
+ | force -freeze sim:/sinal_auto/rst 1 0, 0 0.01 sec | ||
+ | run 25 min | ||
+ | </syntaxhighlight> | ||
+ | --> | ||
+ | {{collapse bottom}} | ||
+ | {{collapse top| expand=true | Unidade 8 - Testbench}} | ||
+ | |||
+ | ===Unidade 8 - Testbench=== | ||
+ | * 2 AULAS | ||
+ | ; Aula 38 (11 nov): | ||
+ | *Simulação de sistemas digitais com Modelsim e testbench em VHDL | ||
+ | :*Tipos de simulação: | ||
+ | ::1) simulação funcional (usando o QSIM) com entrada gráfica e análise gráfica da saída - OK já visto desde CIL29003 | ||
+ | ::2) simulação temporal (usando o QSIM) com entrada gráfica e análise gráfica da saída - OK já visto desde CIL29003 | ||
+ | ::3) simulação funcional (usando o ModelSim) com entrada gráfica (gerado com comandos force) e análise gráfica da saída - OK já visto | ||
+ | ::4) simulação temporal (usando o ModelSim) com entrada gráfica (gerado com comandos force) e análise gráfica da saída - Não será visto | ||
+ | ::5) simulação funcional (usando o ModelSim) com entrada VHDL e análise gráfica da saída - Será visto nesta Unidade | ||
+ | ::6) simulação temporal (usando o ModelSim) com entrada VHDL e análise gráfica da saída - Será visto nesta Unidade | ||
+ | ::7) simulação funcional (usando o ModelSim e Matlab) com entrada VHDL e análise em VHDL da saída. | ||
+ | ::8) simulação temporal (usando o ModelSim e Matlab) com entrada VHDL e análise em VHDL da saída. | ||
+ | :* Simular a maquina de venda de doces Ex 11.1 | ||
+ | |||
+ | <!-- | ||
+ | :*Exemplo de Conversor Binário para Gray (Exercício 9.7) | ||
+ | |||
+ | :*Para usar o ModelSim 10.1d na CLOUD-IFSC(191.36.8.33) abra um terminal e digite: | ||
+ | /opt/altera/13.0sp1/modelsim_ae/bin/vsim | ||
+ | :* ou | ||
+ | vsim | ||
+ | :*Para usar o ModelSim 10.1d nos Laboratórios do IFSC campus São José abra um terminal e digite: | ||
+ | /opt/altera/13.0/quartus/modelsim_ae/linux/vsim | ||
+ | |||
+ | :*Ver também [http://quartushelp.altera.com/13.1/mergedProjects/eda/simulation/modelsim/eda_pro_msim_func_sim.htm Performing a Functional Simulation with the ModelSim-Altera Software], e [http://quartushelp.altera.com/13.1/mergedProjects/eda/simulation/modelsim/eda_pro_msim_timing_sim.htm Performing a Timing Simulation with the ModelSim-Altera Software]. | ||
+ | |||
+ | *Simulação de sistemas digitais com Modelsim e testbench em VHDL | ||
+ | ::*Implementar um sistema constituído de dois circuitos de SHIFT RIGHT LOGICAL - SRL_L com entradas de DADOS, LOAD e RESET, e saída paralela. Crie um componente SOMADOR constituido de um somado do tipo UNSIGNED. Conecte as saídas dos SRL_L ao SOMADOR. | ||
+ | <center> | ||
+ | [[Arquivo:slr_adder.png]] | ||
+ | </center> | ||
+ | |||
+ | ::*Criar um testbench em VHDL para testar cada componente (SOMADOR, o SRL_L) e o sistema final. (faça com o test bench teste no minimo o funcionamento da entrada LOAD para 2 entradas diferentes de DADOS, o RESET, o SOMADOR e o funcionamento do SRL_L para uma sequencia de pelo menos N clocks, onde N é o número de bits das entradas. | ||
+ | |||
+ | ::Note que no final deste projeto, deverão existir pelo menos os arquivos de projeto '''srl_l.vhd''', '''somador.vhd''', '''sistema.vhd''' e os arquivos de teste bench correspondentes '''srl_l_tb.vht''', '''somador_tb.vht''', '''sistema_tb.vht'''. Para facilitar a simulação no Modelsim recomenda-se criar também os arquivos de script '''srl_l.do''', '''somador.do''', '''sistema.do'''. | ||
+ | |||
+ | --> | ||
+ | ::'''DICA''': Use o comando do Quartus II para gerar um template para o testbench. Selecione cada componente como TOP LEVEL e faça a ANÁLISE E SÍNTESE em seguida ('''Processing > Start > Start Test Bench Template Writer'''). | ||
+ | :* Criação de sinais para Test Bench em VHDL | ||
+ | |||
+ | {{collapse top | Geração de sinal de clock}} | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- DECLARAR | ||
+ | constant tclk: time := 1 ns; | ||
+ | signal clk : std_logic := '0'; | ||
+ | |||
+ | -- CLOCK COM PERIODO DE 2*tclk (COM CÓDIGO CONCORRENTE) | ||
+ | clk <= not clk after tclk; | ||
+ | |||
+ | -- CLOCK COM PERIODO DE 2*tclk (COM CÓDIGO SEQUENCIAL) | ||
+ | PROCESS | ||
+ | BEGIN | ||
+ | clk <= '1'; | ||
+ | wait for tclk; | ||
+ | clk <= '0'; | ||
+ | wait for tclk; | ||
+ | END PROCESS; | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | Geração de sinal de reset}} | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- DECLARAR | ||
+ | constant treset: time := 100 ps; | ||
+ | signal reset : std_logic; | ||
+ | |||
+ | -- RESET COM DURAÇÃO DE treset (COM CÓDIGO CONCORRENTE) | ||
+ | reset <= '1', '0' after treset; | ||
+ | |||
+ | -- RESET COM DURAÇÃO DE treset (COM CÓDIGO SEQUENCIAL) | ||
+ | PROCESS | ||
+ | BEGIN | ||
+ | reset <= '1'; | ||
+ | wait for treset; | ||
+ | reset <= '0'; | ||
+ | wait; | ||
+ | END PROCESS; | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | Geração de uma sequencia binária}} | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- DECLARAR | ||
+ | constant t_a: time := 100 ps; | ||
+ | constant Nbits: natural := 8; | ||
+ | signal a : std_logic_vector(Nbits-1 downto 0); | ||
+ | |||
+ | -- GERAÇÂO DO SINAL a = [0 1 2 3 4 ...] COM DURAÇÃO DE t_a em cada valor (COM CÓDIGO SEQUENCIAL) | ||
+ | PROCESS | ||
+ | BEGIN | ||
+ | for i in 0 to 2**Nbits-1 loop | ||
+ | a <= std_logic_vector(to_unsigned(i,Nbits)); | ||
+ | wait for t_a; | ||
+ | end loop; | ||
+ | END PROCESS; | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | Geração de uma sequencia pseudoaleatória}} | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- DECLARAR | ||
+ | constant t_a: time := 100 ps; | ||
+ | constant Nbits: natural := 8; | ||
+ | signal a : std_logic_vector(Nbits-1 downto 0) := (0 => '1', 3 => '1', others => '0'); | ||
+ | |||
+ | -- GERAÇÂO DO SINAL a COM DURAÇÃO DE t_a em cada valor (COM CÓDIGO SEQUENCIAL) | ||
+ | -- USANDO UM CONTADOR LFSR | ||
+ | PROCESS | ||
+ | BEGIN | ||
+ | for i in 0 to 2**Nbits-1 loop | ||
+ | a <= (a(0) xor a(2) xor a(3) xor a(4)) & a(Nbits-1 downto 1); -- para 8 bits | ||
+ | wait for t_a; | ||
+ | end loop; | ||
+ | END PROCESS; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | ; Aula 39 (13 nov): | ||
+ | *Código VHDL da maquina de venda de balas | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --------------------------------- | ||
+ | -- FILE: vende_balas_FSM.vhd | ||
+ | --------------------------------- | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | |||
+ | entity vende_balas_FSM is | ||
+ | port( | ||
+ | rst, clk : in std_logic; | ||
+ | e5c, e10c, e25c: in std_logic; | ||
+ | d5c, d10c: out std_logic; | ||
+ | bala: out std_logic | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ifsc_v1 of vende_balas_FSM is | ||
+ | type state is ( | ||
+ | st0, st5, st10, st15, st20, st25, st30, st35, st40, st45 | ||
+ | ); | ||
+ | signal pr_state, nx_state: state; | ||
+ | begin | ||
+ | process(clk, rst) | ||
+ | begin | ||
+ | if rst = '1' then | ||
+ | pr_state <= st0; | ||
+ | elsif rising_edge(clk) then | ||
+ | pr_state <= nx_state; | ||
+ | end if; | ||
+ | end process; | ||
+ | |||
+ | process(pr_state, e5c, e10c, e25c) | ||
+ | begin | ||
+ | bala <= '0'; | ||
+ | d5c <= '0'; | ||
+ | d10c <= '0'; | ||
+ | case pr_state is | ||
+ | when st0 => | ||
+ | if e5c = '1' then | ||
+ | nx_state <= st5; | ||
+ | elsif e10c = '1' then | ||
+ | nx_state <= st10; | ||
+ | elsif e25c = '1' then | ||
+ | nx_state <= st25; | ||
+ | else | ||
+ | nx_state <= st0; | ||
+ | end if; | ||
+ | when st5 => | ||
+ | if e5c = '1' then | ||
+ | nx_state <= st10; | ||
+ | elsif e10c = '1' then | ||
+ | nx_state <= st15; | ||
+ | elsif e25c = '1' then | ||
+ | nx_state <= st30; | ||
+ | else | ||
+ | nx_state <= st5; | ||
+ | end if; | ||
+ | when st10 => | ||
+ | if e5c = '1' then | ||
+ | nx_state <= st15; | ||
+ | elsif e10c = '1' then | ||
+ | nx_state <= st20; | ||
+ | elsif e25c = '1' then | ||
+ | nx_state <= st35; | ||
+ | else | ||
+ | nx_state <= st10; | ||
+ | end if; | ||
+ | when st15 => | ||
+ | if e5c = '1' then | ||
+ | nx_state <= st20; | ||
+ | elsif e10c = '1' then | ||
+ | nx_state <= st25; | ||
+ | elsif e25c = '1' then | ||
+ | nx_state <= st40; | ||
+ | else | ||
+ | nx_state <= st15; | ||
+ | end if; | ||
+ | when st20 => | ||
+ | if e5c = '1' then | ||
+ | nx_state <= st25; | ||
+ | elsif e10c = '1' then | ||
+ | nx_state <= st30; | ||
+ | elsif e25c = '1' then | ||
+ | nx_state <= st45; | ||
+ | else | ||
+ | nx_state <= st20; | ||
+ | end if; | ||
+ | when st25 => | ||
+ | bala <= '1'; | ||
+ | nx_state <= st0; | ||
+ | when st30 => | ||
+ | d5c <= '1'; | ||
+ | nx_state <= st25; | ||
+ | when st35 => | ||
+ | d10c <= '1'; | ||
+ | bala <= '1'; | ||
+ | nx_state <= st0; | ||
+ | when st40 => | ||
+ | d10c <= '1'; | ||
+ | nx_state <= st30; | ||
+ | when st45 => | ||
+ | d10c <= '1'; | ||
+ | nx_state <= st35; | ||
+ | end case; | ||
+ | end process; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | *Script tb.do para um testbench para Modelsim. | ||
+ | <code> | ||
+ | ################################# | ||
+ | ## FILE: tb.do | ||
+ | ################################# | ||
+ | vcom -93 -work work {../../vende_balas_FSM.vhd} | ||
+ | vsim work.vende_balas_FSM | ||
+ | |||
+ | add wave -position end -color gold sim:/vende_balas_FSM/rst | ||
+ | add wave -position end -color gold sim:/vende_balas_FSM/clk | ||
+ | add wave -position end -color blue sim:/vende_balas_FSM/e5c | ||
+ | add wave -position end -color blue sim:/vende_balas_FSM/e10c | ||
+ | add wave -position end -color blue sim:/vende_balas_FSM/e25c | ||
+ | add wave -position end sim:/vende_balas_FSM/nx_state | ||
+ | add wave -position end sim:/vende_balas_FSM/pr_state | ||
+ | add wave -position end -color red sim:/vende_balas_FSM/bala | ||
+ | add wave -position end -color red sim:/vende_balas_FSM/d5c | ||
+ | add wave -position end -color red sim:/vende_balas_FSM/d10c | ||
+ | configure wave -timelineunits sec | ||
+ | WaveRestoreZoom {0 ps} {25sec} | ||
+ | |||
+ | force -freeze sim:/vende_balas_FSM/rst 1 0, 0 0.1 sec | ||
+ | force -freeze sim:/vende_balas_FSM/clk 0 0, 1 {0.5 sec} -r 1sec | ||
+ | force -freeze sim:/vende_balas_FSM/e5c 0 0, 1 13sec, 0 14sec | ||
+ | force -freeze sim:/vende_balas_FSM/e10c 0 0, 1 16sec, 0 17sec, 1 23sec, 0 24sec | ||
+ | force -freeze sim:/vende_balas_FSM/e25c 0 0, 1 4sec, 0 5sec, 1 9sec, 0 10sec, 1 20sec, 0 21sec | ||
+ | run 25 sec | ||
+ | </syntaxhighlight> | ||
+ | *Resultado da simulação no Modelsim. Execute do tb.do | ||
+ | <center> | ||
+ | [[Arquivo:vende_balas_FSM_sim.png | 800px]] | ||
+ | </center> | ||
+ | *Use o template gerado pelo Quartus e acrescente os estimulos indicados abaixo e realize a simulação usando agora o testbench em VHDL. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | |||
+ | -- constants | ||
+ | constant tclk: time := 0.5 sec; | ||
+ | constant treset: time := 100 ps; | ||
+ | constant talto: time := 1 sec; | ||
+ | |||
+ | -- RESET COM DURAO DE treset (COM CDIGO CONCORRENTE) | ||
+ | sim_rst: rst <= '1', '0' after treset; | ||
+ | |||
+ | -- CLOCK COM PERIODO DE 2*tclk (COM CDIGO SEQUENCIAL) | ||
+ | sim_clk: PROCESS | ||
+ | BEGIN | ||
+ | clk <= '0'; | ||
+ | wait for tclk; | ||
+ | clk <= '1'; | ||
+ | wait for tclk; | ||
+ | END PROCESS; | ||
+ | -- GERAAO DO ESTIMULO "e5c"(COM CDIGO SEQUENCIAL) | ||
+ | sim_e5c: e5c <= '0', '1' after 13 sec, '0' after 14 sec; | ||
+ | |||
+ | -- GERAAO DO ESTIMULO "e5c"(COM CDIGO SEQUENCIAL) | ||
+ | sim_e10c: e10c <= '0', '1' after 16 sec, '0' after 17 sec, '1' after 23 sec, '0' after 24 sec; | ||
+ | |||
+ | -- GERAAO DO ESTIMULO "e25c"(COM CDIGO SEQUENCIAL) | ||
+ | |||
+ | -- sim_e25c: PROCESS | ||
+ | -- BEGIN | ||
+ | -- e25c <= '0'; | ||
+ | -- wait for 4 sec; | ||
+ | -- e25c <= '1'; | ||
+ | -- wait for 1 sec; | ||
+ | -- e25c <= '0'; | ||
+ | -- END PROCESS; | ||
+ | |||
+ | -- Os tempos neste caso sao os intervalos entre os eventos | ||
+ | -- No exemplo acima o SIGNAL e25c inicia com '0', muda para '1' apos 4 segundos, | ||
+ | -- e depois muda para '0' depois de mais 1 segundo | ||
+ | -- em CDIGO SEQUENCIALo mesmo estimulo seria gerado com: | ||
+ | -- sim_e25c: e25c <= '0', '1' after 4 sec, '0' after 5 sec; | ||
+ | |||
+ | sim_e25c: PROCESS | ||
+ | BEGIN | ||
+ | e25c <= '0'; | ||
+ | wait for 4 sec; | ||
+ | e25c <= '1'; | ||
+ | wait for talto; | ||
+ | e25c <= '0'; | ||
+ | wait for 3 sec; | ||
+ | e25c <= '1'; | ||
+ | wait for talto; | ||
+ | e25c <= '0'; | ||
+ | wait for 10 sec; | ||
+ | e25c <= '1'; | ||
+ | wait for talto; | ||
+ | e25c <= '0'; | ||
+ | wait for 5 sec; | ||
+ | END PROCESS; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===ATUAL=== | ||
+ | ;Aula 40 (18 Nov): | ||
+ | |||
+ | * Especificação do projeto final. Ver detalhes abaixo no tópico Projeto Final. | ||
+ | |||
+ | * Definição de uma maquina de estados finita (FSM) para um robô de limpeza de áreas retangulares. (sugerido por ARY HAUFFE NETO) | ||
+ | :*O robô ao ser colocado em uma área retangular ao ser ligado deve ir até o canto superior esquerdo. | ||
+ | :*A limpeza deve ser realizada indo e voltando em linhas paralelas até atingir o canto inferior. | ||
+ | :*Ao atingir o canto inferior o robô deve percorrer todos os quatro lados e fazer a limpeza. | ||
+ | :*Existe um sensor (S) na frente que permite detectar se existe um obstaculo a frente (Sensor = '1') | ||
+ | :*Existe um comando que permite avançar (A) um passo a cada ''clock'' (Avança = '1') | ||
+ | :*Existe um comando que indica para o robô ligar os equipamentos de limpeza (Limpa = '1') | ||
+ | :*Existe um comando para girar o robô 90º no sentido anti-horário (E = '1') ou horário (D = '1'). | ||
+ | :*Implementar a lógica completa da FSM e simular o seu funcionamento para uma área correspondente a 4 passos x 5 passos. | ||
+ | |||
+ | {{collapse top | Cleanbot v1}} | ||
+ | |||
+ | <center> | ||
+ | '''Figura - Projeto da maquina de estados finita do sistema cleanbot v1. Diagrama feito em [[linguagem .dot]].''' | ||
+ | <graphviz> | ||
+ | // FILE: Exemplo_FSM.do | ||
+ | // AUTOR: prof. Marcos Moeck | ||
+ | // Curso de Engenharia de Telecomunicações | ||
+ | // IFSC - Instituto Federal de Santa Catarina | ||
+ | // DATA: 19 nov 2019 | ||
+ | digraph G { | ||
+ | size="12,10!" | ||
+ | labelloc=c fontsize=30 | ||
+ | label ="Cleanbot" | ||
+ | labelloc = t | ||
+ | rankdir = "LR" | ||
+ | //packMode = "clust" | ||
+ | clusterMode = "local" | ||
+ | fixedsize = true | ||
+ | splines = true | ||
+ | node [style=filled, shape=circle, style="rounded,filled"] | ||
+ | // node [width = 2, height = 1,labelloc=c fontsize=17, style=filled, shape=circle, style="rounded,filled"] | ||
+ | |||
+ | edge [arrowsize=0.5] | ||
+ | //Estado inicial | ||
+ | Inicio [shape=Mdiamond]; | ||
+ | Fim [shape=Msquare]; | ||
+ | |||
+ | // Inicialização - ir para o canto superior esquerdo | ||
+ | I1 [color="#7777FF", label = "I1 \nA = 1"] | ||
+ | I2 [color="#7777FF", label = "I2 \nE = 1"] | ||
+ | I3 [color="#7777FF", label = "I3 \nA = 1"] | ||
+ | I4 [color="#7777FF", label = "I4 \nD = 1"] | ||
+ | I5 [color="#7777FF", label = "I5 \nD = 1"] | ||
+ | |||
+ | A1 [color="#77FF77", label = "A1 \nA = 1"] | ||
+ | R1 [color="#77FF77", label = "R1 \nD = 1 \nA=1"] | ||
+ | R2 [color="#77FF77", label = "R2 \nD = 1"] | ||
+ | A2 [color="#77FF77", label = "A2 \nA = 1"] | ||
+ | R3 [color="#77FF77", label = "R3 \nE = 1 \nA = 1"] | ||
+ | R4 [color="#77FF77", label = "R4 \nE = 1"] | ||
+ | |||
+ | Inicio -> W1 [label = "I = 1"] | ||
+ | W1 -> I1 [label = "I = 0"] | ||
+ | I1 -> I2 [label = "S = 1"] | ||
+ | I2 -> I3 | ||
+ | I3 -> I4 [label = "S = 1"] | ||
+ | I4 -> I5 | ||
+ | I5 -> A1 | ||
+ | A1 -> R1 [label = "S = 1"] | ||
+ | R1 -> R2 | ||
+ | R2 -> A2 | ||
+ | A2 -> R3 [label = "S = 1"] | ||
+ | R3 -> R4 | ||
+ | R4 -> A1 | ||
+ | I5 -> W2 [label = "I = 1"] | ||
+ | A1 -> W2 [label = "I = 1"] | ||
+ | A2 -> W2 [label = "I = 1"] | ||
+ | W2 -> Inicio [label = "I = 0"] | ||
+ | R1 -> Fim [label = "S = 1"] | ||
+ | R3 -> Fim [label = "S = 1"] | ||
+ | Fim -> Inicio | ||
+ | |||
+ | subgraph cluster_inicial { | ||
+ | label = "Inicializando"; | ||
+ | style=filled; | ||
+ | color=lightgrey; | ||
+ | labelloc=be fontsize=20 | ||
+ | node [style=filled,color=grey]; | ||
+ | I1 I2 I3 I4 I5 | ||
+ | } | ||
+ | |||
+ | subgraph cluster_descansando { | ||
+ | label = "Descansando"; | ||
+ | style=filled; | ||
+ | color=lightgrey; | ||
+ | labelloc=bd fontsize=20 | ||
+ | node [style=filled,color=grey]; | ||
+ | W1 W2 Inicio Fim | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | subgraph cluster_limpa { | ||
+ | label = "Limpando"; | ||
+ | style=filled; | ||
+ | color=lightgrey; | ||
+ | labelloc=e fontsize=20 | ||
+ | node [style=filled,color=grey]; | ||
+ | A1 A2 R1 R2 R3 R4 | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </graphviz></center> | ||
+ | |||
+ | {{collapse bottom | Cleanbot v1}} | ||
+ | |||
+ | {{collapse top | expand=true | Cleanbot v2}} | ||
+ | |||
+ | <center> | ||
+ | '''Figura - Projeto da maquina de estados finita do sistema cleanbot v2. Diagrama feito em [[linguagem .dot]].''' | ||
+ | <graphviz> | ||
+ | // FILE: Exemplo_FSM.do | ||
+ | // AUTOR: prof. Marcos Moeck | ||
+ | // Curso de Engenharia de Telecomunicações | ||
+ | // IFSC - Instituto Federal de Santa Catarina | ||
+ | // DATA: 19 nov 2019 | ||
+ | digraph G { | ||
+ | size="12,10!" | ||
+ | labelloc=c fontsize=30 | ||
+ | label ="Cleanbot" | ||
+ | type = "twopi" | ||
+ | labelloc = t | ||
+ | rankdir = "LR" | ||
+ | //packMode = "clust" | ||
+ | //clusterMode = "local" | ||
+ | fixedsize = true | ||
+ | splines = true | ||
+ | node [style=filled, shape=circle] | ||
+ | // node [width = 1, height = 1,labelloc=c fontsize=17, style=filled, shape=circle, style="rounded,filled"] | ||
+ | |||
+ | edge [arrowsize=0.9] | ||
+ | |||
+ | //Valor default das saídas | ||
+ | Default [shape=square, fontsize=17, color=grey, label = "DEFAULT \nA = 0 \nL = 0 \nD = 0 \nE = 0"] | ||
+ | |||
+ | //Estado de reset | ||
+ | Reset [width = 0.2, style=filled, shape=circle, color = black, style="rounded,filled", label = "0"] | ||
+ | |||
+ | //Estado inicial | ||
+ | Inicio [shape=Mdiamond]; | ||
+ | //Estado Final | ||
+ | Fim [shape=Msquare]; | ||
+ | |||
+ | // Inicialização - ir para o canto superior esquerdo | ||
+ | I1 [color="#AAAAFF", label = "I1 \n-----------\nA = 1"] | ||
+ | I2 [color="#AAAAFF", label = "I2 \n-----------\nE = 1"] | ||
+ | I3 [color="#AAAAFF", label = "I3 \n-----------\nA = 1"] | ||
+ | I4 [color="#AAAAFF", label = "I4 \n-----------\nD = 1"] | ||
+ | I5 [color="#AAAAFF", label = "I5 \n-----------\nD = 1"] | ||
+ | |||
+ | // Limpando a área - Linha por linha | ||
+ | A1 [color="#77FF77", label = "A1 \n-----------\nA = 1 \nL = 1"] | ||
+ | R1 [color="#77FF77", label = "R1 \n-----------\nD = 1"] | ||
+ | A2 [color="#77FF77", label = "A2 \n-----------\nA = 1"] | ||
+ | R2 [color="#77FF77", label = "R2 \n-----------\nD = 1"] | ||
+ | A3 [color="#77FF77", label = "A3 \n-----------\nA = 1 \nL = 1"] | ||
+ | R3 [color="#77FF77", label = "R3 \n-----------\nE = 1"] | ||
+ | A4 [color="#77FF77", label = "A4 \n-----------\nA = 1"] | ||
+ | R4 [color="#77FF77", label = "R4 \n-----------\nE = 1"] | ||
+ | |||
+ | Reset -> Inicio [label = "reset"] | ||
+ | Inicio -> W1 [label = "I = 1"] | ||
+ | W1 -> I1 [label = "I = 0"] | ||
+ | I1 -> I2 [label = "S = 1"] | ||
+ | I2 -> I3 | ||
+ | I3 -> I4 [label = "S = 1"] | ||
+ | I4 -> I5 | ||
+ | I5 -> A1 | ||
+ | I1 -> W2 [label = "I = 1"] | ||
+ | I3 -> W2 [label = "I = 1"] | ||
+ | W2 -> Inicio [label = "I = 0"] | ||
+ | |||
+ | |||
+ | A1 -> R1 [label = "S = 1"] | ||
+ | R1 -> A2 | ||
+ | A2 -> R2 | ||
+ | R2 -> A3 | ||
+ | A3 -> R3 [label = "S = 1"] | ||
+ | R3 -> A4 | ||
+ | A4 -> R4 | ||
+ | R4 -> A1 | ||
+ | |||
+ | A1 -> W2 [label = "I = 1"] | ||
+ | A3 -> W2 [label = "I = 1"] | ||
+ | R1 -> Fim [label = "S = 1"] | ||
+ | R3 -> Fim [label = "S = 1"] | ||
+ | Fim -> Inicio | ||
+ | |||
+ | subgraph cluster_inicial { | ||
+ | label = "Inicializando"; | ||
+ | style=filled; | ||
+ | color=lightgrey; | ||
+ | fontsize=20 | ||
+ | node [style=filled,color=grey]; | ||
+ | I1 I2 I3 I4 I5 | ||
+ | } | ||
+ | |||
+ | subgraph cluster_descansando { | ||
+ | label = "Descansando"; | ||
+ | style=filled; | ||
+ | color=lightgrey; | ||
+ | fontsize=20 | ||
+ | node [style=filled,color=grey]; | ||
+ | W1 W2 Inicio Fim | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | subgraph cluster_limpa { | ||
+ | label = "Limpando"; | ||
+ | style=filled; | ||
+ | color=lightgrey; | ||
+ | fontsize=20 | ||
+ | node [style=filled,color=grey]; | ||
+ | A1 A2 A3 A4 R1 R2 R3 R4 | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </graphviz></center> | ||
+ | |||
+ | <center> | ||
+ | '''Figura - Maquina de estados finita do sistema cleanbot v2. Diagrama [[FSM do Quartus II]].''' | ||
+ | |||
+ | [[Arquivo:cleanbot_FSMv2.png|1200px]] | ||
+ | </center> | ||
+ | |||
+ | <center> | ||
+ | '''Figura - Simulação da maquina de estados finita do sistema cleanbot v3. Diagrama do Modelsim.''' | ||
+ | |||
+ | [[Arquivo:cleanbot_FSMv2_SIM.png|1200px]] | ||
+ | </center> | ||
+ | {{collapse bottom | Cleanbot v2}} | ||
==Avaliações== | ==Avaliações== | ||
Linha 435: | Linha 2 604: | ||
===Avaliação A1=== | ===Avaliação A1=== | ||
*Conteúdo avaliado serão as unidades 2 a 4 (cap 1 - 5) | *Conteúdo avaliado serão as unidades 2 a 4 (cap 1 - 5) | ||
− | *Data da avaliação ( | + | *Data da avaliação (27/09/2019) - Local: LabSiDi. |
===Avaliação A2=== | ===Avaliação A2=== | ||
− | *Conteúdo avaliado serão as unidades 5 a | + | *Conteúdo avaliado serão as unidades 5 a 8 (Cap 6 a 10) |
− | *Data da avaliação ( | + | *Data da avaliação (29/11/2019) - Local: LabSiDi. |
===Recuperação R12=== | ===Recuperação R12=== | ||
*Esta avaliação somente será realizada se necessária, e deverá ser feita na última semana letiva do semestre | *Esta avaliação somente será realizada se necessária, e deverá ser feita na última semana letiva do semestre | ||
− | *Conteúdo avaliado será as unidades 2 a | + | *Conteúdo avaliado será as unidades 2 a 8 |
*Data da avaliação (XX/XX/2019) - Local: LabSiDi. | *Data da avaliação (XX/XX/2019) - Local: LabSiDi. | ||
Linha 461: | Linha 2 630: | ||
===Projeto Final (PF)=== | ===Projeto Final (PF)=== | ||
* O projeto final é uma atividade de avaliação desenvolvida em equipe, e consiste no desenvolvimento de um sistema que aplica os conhecimento adquiridos durante o semestre. A avaliação do projeto final corresponde a no mínimo 45% do peso no conceito final. São avaliados no projeto final os quesitos: 1) Sistema desenvolvido (projeto, simulação e realização, demostração do harware); 2) Relatório com a documentação completa do projeto; 3) A avaliação individual do aluno durante o desenvolvimento do projeto e/ou entrevista (avaliação oral). | * O projeto final é uma atividade de avaliação desenvolvida em equipe, e consiste no desenvolvimento de um sistema que aplica os conhecimento adquiridos durante o semestre. A avaliação do projeto final corresponde a no mínimo 45% do peso no conceito final. São avaliados no projeto final os quesitos: 1) Sistema desenvolvido (projeto, simulação e realização, demostração do harware); 2) Relatório com a documentação completa do projeto; 3) A avaliação individual do aluno durante o desenvolvimento do projeto e/ou entrevista (avaliação oral). | ||
+ | |||
+ | * O objeto do projeto deste semestre é um sistema de controle de tráfego semafórico para carros, pedestres e ambulâncias na região da praia comprida. | ||
+ | <center>[[Arquivo:MapaPraiaCompridaSJ-IFSC.png| 800px]]</center> | ||
+ | |||
+ | <center>[[Arquivo:Mapa2PraiaCompridaSJ-IFSC.png| 800px]]</center> | ||
+ | |||
+ | FONTE: https://www.google.com.br/maps/@-27.6068859,-48.6298234,17.21z | ||
+ | |||
+ | * Cada equipe deverá apresentar um projeto de sistema semafórico que resolva os principais entroncamentos de acesso ao IFSC (chegada e saída). | ||
+ | * É permitido inverter o fluxo das ruas se necessário. | ||
+ | * Todas equipes deverão pensar em soluções que facilitem a passagem de '''ambulância''' em direção ao Hospital Regional seja vindo da BR ou da Praia Comprida. | ||
+ | :*Sugestão: A ambulância aciona um botão ao avistar o semáforo, e libera o botão ao passar pelo semáforo. Ao ser acionado o botão o semáforo deverá mudar a via da ambulância para verde após fechar a outra via (Amarelo-Vermelho). Após a passagem da ambulância o semáforo retorna ao funcionamento normal. | ||
+ | * Os semáforos empregados deverão ter indicação de contagem de tempo de verde e vermelho. | ||
+ | * Deverá haver semáforos de pedestres para facilitar a chegada ao IFSC e também ao Hospital Regional. | ||
+ | :<center>[[Arquivo:SemaforoPedestres.png| 800px]]</center> | ||
+ | :* Considere o percurso que o pedestre faz ao vir dos principais pontos de ônibus e vias da região. Sempre deverá haver um caminho de pedestre usando semáforos. Deverá ser mostrado em um mapa os percursos seguros dos pedestres. | ||
+ | * As equipes deverão sugerir os tempos de verde, amarelo e vermelho para todos semáforos dos cruzamentos principais da região. | ||
+ | * Os sistemas projetados deverão ser configuráveis. | ||
+ | * A configuração de acordo com o horário do dia é ponto de BONUS. | ||
+ | * Os sistemas deverão ser sincronizados, de modo a atuarem em conjunto. | ||
+ | * Os semáforos deverão dispor de botões para controle manual pela '''guarda municipal'''. | ||
+ | :*Sugestão: usar um código de chaves que indique: a) semáforo no automático; b) semáforo aberto para a via 1; c) semáforo aberto para a via 2; ... d) semáforo aberto para passagem de pedestres (se necessário). | ||
+ | * Os projetos deverão ser implantados em kits FPGA, podendo ser usados mais de um kit para as soluções. | ||
+ | |||
+ | * O projeto será realizado em etapas. | ||
+ | :1) Posicionamento de todos os semáforos da região no mapa, e indicação de quais a equipe irá implementar. | ||
+ | :2) Identificação fotográfica dos pontos onde os semáforos a ser implementados serão hipoteticamente instalados. | ||
+ | :3) Os tempos de abertura e fechamento de todos os semáforos da região (não apenas os que serão implementados). | ||
+ | :4) Contagem do tráfego de veículos nas vias dos entroncamentos a serem atendidos pelo tempo de XX minutos (no horário de rush e normal). | ||
+ | :5) Projeto dos módulos, simulação e realização em FPGA. | ||
+ | |||
+ | ;Requisitos gerais: | ||
+ | *Cada equipe deverá projetar os semáforos para dois entroncamentos de ruas, podendo ser ruas de 2 tempos até 4 tempos. Semáforo de N tempos significa que existem N momentos distintos de verde. | ||
+ | *O semáforo para travessia de pedestres (GFPp) deverá funcionar a partir do acionamento do botão de solicitação de travessia ('''B_travessia'''). A temporização do mesmo deve ser tal que evite o fechamento do tráfego para carros em intervalos menores que '''tmin_carro''' minutos. Quando esse tempo estiver esgotado o semáforo dos carros deverá estar em verde e o de pedestre em vermelho. Ao acionar o botão o tempo para o mínimo para a parada com segurança dos carros. O tempo de travessia deverá ser relativo a distância a ser percorrida pela pedestre. | ||
+ | :*A travessia de pedestres deverá ter uma iluminação, que será acesa a noite assim que o botão '''B_travessia''' for acionado. Quando o GFPp passar de verde para vermelho, a iluminação deverá apagar. | ||
+ | :*O tempo de passagem do pedestre (T_travessia) é configurável (default = 5s x Nvias). | ||
+ | *Os semáforos de carros deverão ser instâncias de um semáforo genérico projetado para atender diferentes necessidades dos entroncamentos. | ||
+ | *Todos os tempos dos semáforos deverão ser configuráveis através de valores GENERIC. | ||
+ | *Pelo menos um dos semáforos deverá ter mostradores de sete segmentos de 2 dígitos para mostrar o tempo de verde e vermelho. | ||
+ | *Os semáforos de carros de cada via deverão ser do tipo progressivo ou com mostrador. | ||
+ | *O sistema de controle de cada entroncamento deverá será baseado em FSM com clock de temporização de 1 segundo. | ||
+ | *O sistema será implementado no kit FPGA DE2-115 usando os leds disponíveis ou pinos da GPIO para acionar leds externos, e chaves para implementar os botões (pedestre, ambulância, guarda). | ||
+ | *Os sinais de relógio necessários deverão ser obtidos a partir do sinal de clock da placa de 50MHz. Durante as simulações esse circuito deverá ter seu valor alterado de modo a viabilizar a simulação. | ||
+ | |||
+ | ;Ver inspirações adicionais para o projeto em: | ||
+ | * [http://www.planalto.gov.br/ccivil_03/LEIS/L9503Compilado.htm Código de Trânsito Brasileiro - LEI Nº 9.503, DE 23 DE SETEMBRO DE 1997], Art 68 a 71 | ||
+ | * Cálculo da distância de parada de um veículo [http://vias-seguras.com/educacao/aulas_de_educacao_no_transito/aula_09_velocidade_e_distancia_de_parada]. | ||
+ | * Exemplo de uma travessia de pedestre [https://www.google.co.uk/maps/@52.6247006,1.247869,3a,49.2y,188.5h,86.4t/data=!3m6!1e1!3m4!1sESWmhMS0FZQ0elZMfTGvMw!2e0!7i13312!8i6656] | ||
+ | * Tipos de travessia de pedestre no Reino Unido [https://www.driving-school-beckenham.co.uk/pedestriancrossings.html] | ||
+ | * Módulo Semáforo LED [https://www.filipeflop.com/produto/modulo-semaforo-led/] | ||
+ | |||
+ | ;Serão dadas três bonificações no projeto: | ||
+ | 1) ('''BONUS 1 ponto''') para a equipe que desenvolver a melhoria que for considerada a melhor pelo cliente. | ||
+ | 2) ('''BONUS 1 ponto''') para primeira equipe que apresentar o projeto sumulado e funcionando no kit FPGA. | ||
+ | |||
+ | ===Estudos livres sem entrega de documentação (EL)=== | ||
+ | *Os estudos livres são fortemente recomendados aos alunos como forma de melhor compreender o assunto estudado em cada unidade. Nas listas de exemplos e exercícios, os essenciais estão destacados em negrito. Não há prazos nem entregas desses estudos no Moodle, mas pede-se que os alunos realizem esses estudos e tirem suas dúvidas nas aulas destinadas a resolução de exercícios, ou nos minutos iniciais das aulas. | ||
+ | |||
+ | {{collapse top | EL1 - Resolução dos exercícios do Cap 2}} | ||
+ | *Resolva os exercícios do capítulo 2 (1, 2, 3) pag. 28 a 30 | ||
+ | ;Exercise 2.1: Multiplexer: | ||
+ | |||
+ | *Complete o código VHDL abaixo para que ele seja correspondente a um multiplexador que selecione a entrada A quando sel ="01", B quando sel ="10", coloque "0...0" na saída quando sel ="00" e mantenha a saída em alta impedância "Z...Z" quando sel="11". | ||
+ | ::*Compile o código e em seguida faça a simulação, para verificar se o circuito funciona conforme | ||
+ | especificado. | ||
+ | ::*Anote as mensagens de warning do compilador. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --------------------------------------- | ||
+ | -- File: mux.vdh | ||
+ | --------------------------------------- | ||
+ | -- Declaração das Bibliotecas e Pacotes | ||
+ | -- | ||
+ | LIBRARY ieee; | ||
+ | USE _________________________ ; | ||
+ | |||
+ | --------------------------------------- | ||
+ | -- Especificação das entradas e saídas e nome da ENTITY | ||
+ | ENTITY mux IS | ||
+ | PORT ( | ||
+ | __ , __ : ___ STD_LOGIC_VECTOR (7 DOWNTO 0); | ||
+ | sel : IN ____________________________ ; | ||
+ | ___ : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)); | ||
+ | END _____ ; | ||
+ | --------------------------------------- | ||
+ | ARCHITECTURE example OF _____ IS | ||
+ | BEGIN | ||
+ | PROCESS (a, b, ____ ) | ||
+ | BEGIN | ||
+ | IF (sel = "00") THEN | ||
+ | c <= "00000000"; | ||
+ | ELSIF (__________) THEN | ||
+ | c <= a; | ||
+ | _____ (sel = "10") THEN | ||
+ | c <= __; | ||
+ | ELSE | ||
+ | c <= (OTHERS => '__'); | ||
+ | END ___ ; | ||
+ | END _________ ; | ||
+ | END _________ ; | ||
+ | --------------------------------------- | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | EL2 - Resolução dos exercícios do Cap 3}} | ||
+ | *Resolva os exercícios do capítulo 3 (1, 2, '''9''', 11, 12, 13, 14-17, '''18-20''', '''22''', 23-30) pag. 81 a 89 | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | EL3 - Resolução dos exercícios do Cap 4}} | ||
+ | *Resolva os exercícios do capítulo 4 (4-8, '''9''', 10-11, 13, 15-16, '''17''' ) pag. 115 a 120 | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | EL4 - Resolução dos exercícios do Cap 5}} | ||
+ | *Resolva os exercícios do capítulo 5 (1, 2, '''3''', 4, '''6''', '''7''', 8-9, '''10-11''', '''14-16''', 17-18, '''19''' ) pag. 144 a 150 | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | EL6 - Resolução dos exercícios do Cap 6}} | ||
+ | *Resolva os exercícios do capítulo 6 (1, '''2''', 3-4, '''5''', 6-7, '''9*''', '''10-11''', 12*, 13*, '''14''', 15*) pag. 172 a 176. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | EL7 - Resolução dos exercícios do Cap 7}} | ||
+ | *Resolva os exercícios da capítulo 7 (9-10) pag. 197. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | EL8 - Resolução dos exercícios do Cap 8}} | ||
+ | *Resolva os exercícios da capítulo 8 (1-7, 9*) pag. 219 a 220. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | EL9 - Resolução dos exercícios do Cap 9}} | ||
+ | *Resolva os exercícios da capítulo 9 (1-4, 6-9) pag. 238 a 239. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | EL10 - Resolução dos exercícios do Cap 10}} | ||
+ | *Resolva os exercícios da capítulo 10 (1,2,5-7, 10-15, 17**) pag. 271 a 274. | ||
+ | :*Na simulação de cada exercício, faça um versão usando comandos force e run e outra com testbench em vhdl. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ==Referências Bibliográficas:== | ||
+ | <references/> | ||
+ | |||
+ | {{ENGTELECO}} |
Edição atual tal como às 15h32min de 18 de agosto 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 2 - Introdução ao VHDL e ambienta EDA - QUARTUS
- 3 AULAS
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;
-- 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;
![]()
![]()
![]()
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
![]()
Video motivational para apreender FPGA, VHDL Microsoft's Bing* Intelligent Search with Intel® FPGAs
![]() ![]() 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 {*}]
/opt/altera/13.0sp1/modelsim_ae/bin/vsim
cd /home/nome_usuario/nome_pasta/...
pwd ls
vlib work vcom -work work n_flip_flop.vhd
vsim work.n_flip_flop
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.
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
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
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
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: ![]()
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: ![]()
Use os comandos da janela de transcript para criar um arquivo tb_FF.do que permite repetir de forma automatica o teste realizado. ################################
# 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
|
Unidade 3 - Tipos de Dados e Operadores em VHDL
- 7 AULAS
Unidade 3 - Tipos de Dados e Operadores em VHDL | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
-- 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;
Ver pag. 60 a 73 de [2]
x = "1----" -- não funciona em VHDL
std_match(x, "1----") -- funciona em 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;
Figura - RTL do conversor de Binário para BCD com 2 digitos Figura - Simulação do conversor de Binário para BCD com 2 digitos
Atributos em VHDL.
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:
type fruit is (apple, orange, pear, mango);
attribute enum_encoding : string;
attribute enum_encoding of fruit : type is "11 01 10 00";
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;
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. .
O atributo de síntese KEEP, sinaliza ao processo de "Analysis & Synthesis" para manter intacto um determinado signal ou componente. signal a,b,c : std_logic;
attribute keep: boolean;
attribute keep of a,b,c: signal is true;
signal a,b,c : std_logic;
attribute preserve: boolean;
attribute preserve of a,b,c: signal is true;
signal reg1: std_logic;
attribute noprune: boolean;
attribute noprune of reg1: signal is true;
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;
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 12. Technology Map do Circuito sem Attribute ![]() Fig 13. Technology Map do Circuito com Attribute Preserve (or Keep) ![]() Fig 14. Technology Map do Circuito com Attribute Noprune
attribute attribute_name: attribute_type;
attribute attribute_name of entity_tag [signature]: entity_class is value;
Exemplo:
Uso da instrução ALIAS.
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;
|
Unidade 4 - Código Concorrente
- 4 AULAS
Unidade 4 - Código Concorrente |
---|
<optional_label>: <target> <=
<value> when <condition> else
<value> when <condition> else
<value> when <condition> else
...
<value>;
<optional_label>: with <expression> select
<target> <=
<value> when <choices>,
<value> when <choices>,
<value> when <choices>,
...
<value> when others;
CONFIGURATION which_mux OF mux IS
FOR Operator_only END FOR;
-- FOR with_WHEN END FOR;
-- FOR with_SELECT END FOR;
END CONFIGURATION;
label: FOR identificador IN faixa GENERATE
[Parte_Declarativa
BEGIN]
Instruções_concorrentes
...
END GENERATE [label];
---------------------
-- FILE my_pkg.vhd --
---------------------
library ieee;
use ieee.std_logic_1164.all;
package my_pkg is
type a_slv is array(natural range <>) of std_logic_vector (3 downto 0);
end package;
---------------------------
-- FILE vector_adder.vhd --
---------------------------
library ieee work;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.my_pkg.all;
entity vector_adder is
generic (N : natural := 4);
port (
a : in a_slv (0 to N-1);
soma : out std_logic_vector (3 downto 0));
end entity;
-- Versão que realiza a soma diretamente, mas que precisa modificar o código de acordo com o número de entradas.
architecture ifsc_v1 of vector_adder is
signal soma_sig : signed(3 downto 0);
begin
soma_sig <= signed(a(0)) + signed(a(1)) + signed(a(2)) + signed(a(3));
soma <= std_logic_vector(soma_sig);
end architecture;
-- Versão que realiza a soma usando um FOR GENERATE
architecture ifsc_v2 of vector_adder is
begin
end architecture;
---------------------------
-- FILE vector_adder.vhd --
---------------------------
configuration ifsc_cfg of vector_adder is
-- for ifsc_v1 end for;
for ifsc_v2 end for;
end configuration;
entity bin2gray is
generic (N : natural := 4 )
port
(
b : in std_logic_vector(____)
g : out std_logic_vector(____)
)
end entity
architecture ifsc of ____ is
begin
end architecture
entity gray2bin is
generic (N : natural := 4 )
port
(
g : in std_logic_vector(____)
b : out std_logic_vector(____)
)
end entity
architecture ifsc of ____ is
begin
end architecture
entity inc_gray is
port
(
gray_in : in std_logic_vector(____)
bray_out : out std_logic_vector(____)
)
end entity
architecture ____ of inc_gray is
begin
end architecture
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.
|
Unidade 5 - Código Sequencial
- 7 AULAS
Unidade 5 - Código Sequencial |
---|
[rótulo:] PROCESS [(lista_de_sensibilidade)] [IS]
[parte_declarativa]
BEGIN
afirmação_sequencial;
afirmação_sequencial;
...
END PROCESS [rótulo];
[rótulo:] IF condição THEN
afirmação_sequencial;
afirmação_sequencial;
...
ELSIF condição THEN
afirmação_sequencial;
afirmação_sequencial;
...
ELSE
afirmação_sequencial;
afirmação_sequencial;
...
END IF [rótulo];
[rótulo:] LOOP
afirmação_sequencial;
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] FOR identificador IN faixa LOOP
afirmação_sequencial;
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] WHILE condição LOOP -- Executa as "afirmações enquanto a "condição" for verdadeira
afirmação_sequencial;
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] [FOR identificador IN faixa] LOOP
afirmação_sequencial;
EXIT [rótulo] [WHEN condição]; -- Se a "condição" é verdadeira, termina o "LOOP"
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] [FOR identificador IN faixa] LOOP
afirmação_sequencial;
NEXT [rótulo] [WHEN condição]; -- Se a "condição" é verdadeira, não executa as linhas até a linha "END LOOP"
-- e incrementa o "identificador".
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] CASE expressão IS
WHEN valor => atribuições; -- valor único
...
WHEN valor1 | valor2 | ... | valorN => atribuições; -- lista de valores
...
WHEN valor1 TO valor2 => atribuições; -- faixa de valores
...
END CASE;
ssd_out <= not ssd;
|
Unidade 6 - Projeto a nível de Sistema
- 8 AULAS
Unidade 6 - Projeto a nível de Sistema | ||||
---|---|---|---|---|
Assim a entity Timer00_99 ENTITY timer00_99seg
GENERIC (D : INTEGER;
fclock : INTEGER;
U : INTEGER);
PORT (clk50MHz : IN STD_LOGIC;
RST : IN STD_LOGIC;
clk1seg : OUT STD_LOGIC;
SSD_Dseg : OUT STD_LOGIC_VECTOR(0 TO 6);
SSD_Useg : OUT STD_LOGIC_VECTOR(0 TO 6));
END ENTITY;
Será declarada como um COMPONENT COMPONENT timer00_99seg
GENERIC (D : INTEGER;
fclock : INTEGER;
U : INTEGER);
PORT (clk50MHz : IN STD_LOGIC;
RST : IN STD_LOGIC;
clk1seg : OUT STD_LOGIC;
SSD_Dseg : OUT STD_LOGIC_VECTOR(0 TO 6);
SSD_Useg : OUT STD_LOGIC_VECTOR(0 TO 6));
END COMPONENT;
comp1 : timer00_99seg
GENERIC MAP (2, 10, 3)
PORT MAP (clk50MHz,RST, clk1seg, SSD_Dseg, SSD_Useg);
comp1 : timer00_99seg
GENERIC MAP ( D => 2, U => 3,
fclock => 10,
PORT MAP ( clk50MHz => clk50MHz,
RST => RST,
clk1seg => clk1seg,
SSD_Dseg => SSD_Dseg,
SSD_Useg => SSD_Useg);
entity timer00_99seg IS
generic (fclk2 : natural := 50, D : natural := 5; U : natural := 9);
port
(
clk50MHz : in STD_LOGIC;
clk_1seg: out STD_LOGIC;
ssd_D : out STD_LOGIC_VECTOR(0 TO 6);
ssd_U : out STD_LOGIC_VECTOR(0 TO 6)
);
end entity;
component div_clk is
generic (fclk2 : natural := 50); -- frequecia para simulacao
port (
clk : in std_logic;
clk_out : out std_logic
);
end component;
;OBS:
*O valor do fclk2 corresponde a metade do período do clock de entrada em Hz.
component count00_99 is
generic (D : natural := 9; U : natural := 9);
port (
clk : in std_logic;
clk_out : out std_logic;
bcd_U : out std_logic_vector(3 downto 0);
bcd_D : out std_logic_vector(3 downto 0)
);
end component;
component bin2ssd is
generic (ac_ccn : natural := 0);
port (
bin_in : in std_logic_vector(3 downto 0);
ssd_out : out std_logic_vector(0 to 6)
);
end component;
OBS: É recomendável inserir um sinal de RESET em todos os circuitos sequenciais e ao iniciar a simulação do circuito começar com RESET ativo durante 10 ps.
|
Unidade 7 - Maquinas de Estado Finitas
Unidade 7 - Maquinas de Estado Finitas |
---|
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
----------------------------------------------------------
ENTITY < entity_name > IS
PORT (
clk, rst : IN STD_LOGIC;
input : IN < data_type > ;
output : OUT < data_type >);
END < entity_name > ;
----------------------------------------------------------
ARCHITECTURE < architecture_name > OF < entity_name > IS
TYPE state IS (A, B, C, ...);
SIGNAL pr_state, nx_state : state;
ATTRIBUTE ENUM_ENCODING : STRING; --optional attribute
ATTRIBUTE ENUM_ENCODING OF state : TYPE IS "sequential";
BEGIN
------Logica Sequencial da FSM:------------
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
pr_state <= A;
ELSIF (clk'EVENT AND clk = '1') THEN
pr_state <= nx_state;
END IF;
END PROCESS;
------Logica Combinacional da FSM:------------
PROCESS (pr_state, input)
BEGIN
------Valores default das saidas------------
output <= < value > ;
CASE pr_state IS
WHEN A =>
output <= < value > ; -- apenas se diferente do valor default
IF (input =< value >) THEN
nx_state <= B;
...
ELSE
nx_state <= A;
END IF;
WHEN B =>
output <= < value > ; -- apenas se diferente do valor default
IF (input =< value >) THEN
nx_state <= C;
...
ELSE
nx_state <= B;
END IF;
WHEN ...
END CASE;
END PROCESS;
------Seção de Saída (opcional):-------
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
new_output <= < value > ;
ELSIF (clk'EVENT AND clk = '1') THEN --or clk='0'
new_output <= output;
END IF;
END PROCESS;
END < architecture_name > ;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
----------------------------------------------------------
ENTITY < entity_name > IS
PORT (
clk, rst : IN STD_LOGIC;
input : IN < data_type > ;
output : OUT < data_type >);
END < entity_name > ;
----------------------------------------------------------
ARCHITECTURE < architecture_name > OF < entity_name > IS
TYPE state IS (A, B, C, ...);
SIGNAL pr_state, nx_state : state;
signal timer: integer range 0 to MAX;
-- ATTRIBUTE ENUM_ENCODING : STRING; --optional attribute
-- ATTRIBUTE ENUM_ENCODING OF state : TYPE IS "sequential";
BEGIN
------Logica Sequencial da FSM:------------
PROCESS (clk, rst)
variable count: integer range o to MAX;
BEGIN
IF (rst = '1') THEN
pr_state <= A;
count := 0;
ELSIF (clk'EVENT AND clk = '1') THEN
count := count + 1;
if (count >= timer) then
pr_state <= nx_state;
count := 0;
end if;
END IF;
END PROCESS;
------Logica Combinacional da FSM:------------
PROCESS (pr_state, input)
BEGIN
------Valores default das saidas------------
output <= < value >;
------Valores default do timer------------
timer <= <value>;
CASE pr_state IS
WHEN A =>
output <= < value > ; -- apenas se diferente do valor default
IF (input =< value >) THEN
timer <= <value>; -- apenas se diferente do valor default
nx_state <= B;
...
ELSE
timer <= <value>; -- apenas se diferente do valor default
nx_state <= A;
END IF;
WHEN B =>
output <= < value > ; -- apenas se diferente do valor default
IF (input =< value >) THEN
timer <= <value>; -- apenas se diferente do valor default
nx_state <= C;
...
ELSE
timer <= <value>; -- apenas se diferente do valor default
nx_state <= B;
END IF;
WHEN ...
END CASE;
END PROCESS;
------Seção de Saída (opcional):-------
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
new_output <= < value > ;
ELSIF (clk'EVENT AND clk = '1') THEN --or clk='0'
new_output <= output;
END IF;
END PROCESS;
END < architecture_name > ;
|
Unidade 8 - Testbench | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Unidade 8 - Testbench
---------------------------------
-- FILE: vende_balas_FSM.vhd
---------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity vende_balas_FSM is
port(
rst, clk : in std_logic;
e5c, e10c, e25c: in std_logic;
d5c, d10c: out std_logic;
bala: out std_logic
);
end entity;
architecture ifsc_v1 of vende_balas_FSM is
type state is (
st0, st5, st10, st15, st20, st25, st30, st35, st40, st45
);
signal pr_state, nx_state: state;
begin
process(clk, rst)
begin
if rst = '1' then
pr_state <= st0;
elsif rising_edge(clk) then
pr_state <= nx_state;
end if;
end process;
process(pr_state, e5c, e10c, e25c)
begin
bala <= '0';
d5c <= '0';
d10c <= '0';
case pr_state is
when st0 =>
if e5c = '1' then
nx_state <= st5;
elsif e10c = '1' then
nx_state <= st10;
elsif e25c = '1' then
nx_state <= st25;
else
nx_state <= st0;
end if;
when st5 =>
if e5c = '1' then
nx_state <= st10;
elsif e10c = '1' then
nx_state <= st15;
elsif e25c = '1' then
nx_state <= st30;
else
nx_state <= st5;
end if;
when st10 =>
if e5c = '1' then
nx_state <= st15;
elsif e10c = '1' then
nx_state <= st20;
elsif e25c = '1' then
nx_state <= st35;
else
nx_state <= st10;
end if;
when st15 =>
if e5c = '1' then
nx_state <= st20;
elsif e10c = '1' then
nx_state <= st25;
elsif e25c = '1' then
nx_state <= st40;
else
nx_state <= st15;
end if;
when st20 =>
if e5c = '1' then
nx_state <= st25;
elsif e10c = '1' then
nx_state <= st30;
elsif e25c = '1' then
nx_state <= st45;
else
nx_state <= st20;
end if;
when st25 =>
bala <= '1';
nx_state <= st0;
when st30 =>
d5c <= '1';
nx_state <= st25;
when st35 =>
d10c <= '1';
bala <= '1';
nx_state <= st0;
when st40 =>
d10c <= '1';
nx_state <= st30;
when st45 =>
d10c <= '1';
nx_state <= st35;
end case;
end process;
end architecture;
|