Mudanças entre as edições de "DLP29006-Engtelecom(2020-2) - Prof. Marcos Moecke"
(110 revisões intermediárias pelo mesmo usuário não estão sendo mostradas) | |||
Linha 4: | Linha 4: | ||
* 3 AULAS | * 3 AULAS | ||
− | {{collapse top | + | {{collapse top | Unidade 1 - Introdução a disciplina}} |
;Aula 1 (9 Nov): | ;Aula 1 (9 Nov): | ||
Linha 51: | Linha 51: | ||
::* [https://en.wikipedia.org/wiki/Field-programmable_gate_array#Major_manufacturers FPGA Major manufacturers] | ::* [https://en.wikipedia.org/wiki/Field-programmable_gate_array#Major_manufacturers FPGA Major manufacturers] | ||
− | |||
;Aula 3 (12 nov): | ;Aula 3 (12 nov): | ||
* Arquitetura de FPGAs (Xilinx e Altera): CLB, LAB, RAM, DSP, Clock, PLL, I/O | * Arquitetura de FPGAs (Xilinx e Altera): CLB, LAB, RAM, DSP, Clock, PLL, I/O | ||
{{collapse top | Exemplos de FPGA}} | {{collapse top | Exemplos de FPGA}} | ||
− | {{fig|1.7|Arquitetura simplificada de FPGA da Intel/Altera e Xilinx | ArquiteturaFPGAs.png| | + | {{fig|1.7|Arquitetura simplificada de FPGA da Intel/Altera e Xilinx | ArquiteturaFPGAs.png| 600 px | <ref name="PEDRONI2010a"> PEDRONI, Volnei A. Eletrônica digital moderna e VHDL; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. . ISBN 9788535234657 </ref> pag. 423}} |
{{fig|1.8|Diagrama simplificado da Slice L de um FPGA Xilinx | SliceL_FPGAs.png| 600 px | <ref name="PEDRONI2010a"> PEDRONI, Volnei A. Eletrônica digital moderna e VHDL; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. . ISBN 9788535234657 </ref> pag. 424}} | {{fig|1.8|Diagrama simplificado da Slice L de um FPGA Xilinx | SliceL_FPGAs.png| 600 px | <ref name="PEDRONI2010a"> PEDRONI, Volnei A. Eletrônica digital moderna e VHDL; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. . ISBN 9788535234657 </ref> pag. 424}} | ||
Linha 62: | Linha 61: | ||
{{fig|1.9|Diagrama simplificado da ALM de um FPGA Intel/Altera | ALM_FPGAs.png| 600 px | <ref name="PEDRONI2010a"> PEDRONI, Volnei A. Eletrônica digital moderna e VHDL; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. . ISBN 9788535234657 </ref> pag. 425}} | {{fig|1.9|Diagrama simplificado da ALM de um FPGA Intel/Altera | ALM_FPGAs.png| 600 px | <ref name="PEDRONI2010a"> PEDRONI, Volnei A. Eletrônica digital moderna e VHDL; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. . ISBN 9788535234657 </ref> pag. 425}} | ||
− | {{fig|1.10|Leiaute de um FPGA Intel/Altera | Leiaute_FPGAs.png| | + | {{fig|1.10|Leiaute de um FPGA Intel/Altera | Leiaute_FPGAs.png| 600 px | <ref name="PEDRONI2010a"> PEDRONI, Volnei A. Eletrônica digital moderna e VHDL; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. . ISBN 9788535234657 </ref> pag. 426}} |
+ | |||
+ | {{fig|1.11|Leiaute de um FPGA Xilinx genérico | Leiaute2_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }} | ||
+ | |||
+ | {{fig|1.12|Roteamento de sinal em um FPGA | Roteamento_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }} | ||
− | {{fig|1. | + | {{fig|1.13|Tecnologias usadas na configuração de FPGAs| FPGA_programming.png| 800 px | https://www.sciencedirect.com/topics/computer-science/one-time-programmable }} |
{{collapse bottom}} | {{collapse bottom}} | ||
Linha 92: | Linha 95: | ||
{{collapse bottom}} | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS=== | ||
+ | * 3 AULAS | ||
+ | {{collapse top| Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS}} | ||
+ | |||
+ | ;Aula 4 (16 nov): | ||
+ | * Introdução ao VHDL e ambiente EDA - QUARTUS | ||
+ | |||
+ | {{fig|2.1|Fluxo simplificado do projeto de FPGA| FPGA_project_low.png| 600 px |}} | ||
+ | |||
+ | :* Ferramentas de projeto | ||
+ | ::*Altera|Intel: Quartus II, [https://www.intel.com/content/www/us/en/software/programmable/overview.html Quartus Prime] (síntese, simulação gráfica e programação do dispositivo) | ||
+ | ::*Xilinx|AMD: [https://www.xilinx.com/products/design-tools/ise-design-suite.html ISE] e [https://www.xilinx.com/products/design-tools/vivado.html Vivado] (síntese, simulação gráfica e programação do dispositivo) | ||
+ | ::*Mentor Graphics: [https://www.mentor.com/products/fpga/synthesis/ Precision RTL Plus + LeonardoSpectrum] (síntese), [https://www.mentor.com/products/fpga/verification-simulation/modelsim/ Modelsim] (projeto e simulação) | ||
+ | ::*Mathworks: Matlab/Simulink/HDL Coder (projeto e simulação) | ||
+ | |||
+ | * Estrutura do código VHDL | ||
+ | :* Declaração das bibliotecas e pacotes '''LIBRARY''' / '''PACKAGE''' | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | library library_name; | ||
+ | use library_name.package_name.all; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* '''ENTITY''' | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | 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]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* '''ARCHITECTURE''' | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | architecture arch_name of entity_name is | ||
+ | [declarative_part] | ||
+ | begin | ||
+ | statement_part | ||
+ | end [architecture] [arch_name]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Exemplo - Declaração de uma porta NAND em VHDL | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | 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; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Exemplo 2.2 (VHDL) - programação de um flip-flop | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- 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; | ||
+ | </syntaxhighlight> | ||
+ | :* Após a [[criação do projeto em VHDL]] utilizando a descrição de hardware acima, [[compile o código VHDL]]. | ||
+ | :* Use o [[RTL Viewer]] para ver a descrição RTL do circuito. | ||
+ | {{fig|2.2|Código RTL do Exemplo 2.2| RTL_Ex2_2_Pedronib.png| 400 px |}} | ||
+ | |||
+ | :* Use o [[Technology Map Viewer]] para ver a como o circuito foi mapeado para os elementos lógicos disponíveis no dispositivo FPGA selecionado (EP1C3T100A8) | ||
+ | {{fig|2.3|Technology Map do Exemplo 2.2| TM_Ex2_2_Pedronib.png| 400 px |}} | ||
+ | |||
+ | :* Abra o [[Chip Planner]] e observe no [[Node Properties]] como esse circuito é conectado dentro do dispositivo FPGA selecionado | ||
+ | {{fig|2.4|Chip Planner do Exemplo 2.2| ChipPlanner_Ex2_2_Pedronib.png| 400 px |}} | ||
+ | |||
+ | :* Modifique o circuito do flip-flop para que ele passe a ter 4 flip-flops | ||
+ | {{fig|2.5|RTL 4 FF| RTL_4FF.png| 400 px |}} | ||
+ | |||
+ | ;Aula 5 (19 nov): | ||
+ | :*Realize as simulações funcional e temporal do circuito com 4 FF usando o QSIM. | ||
+ | {{fig|2.6|Simulação Funcional de 4 FF 100ns| SIM1_4FF.png| 600 px |}} | ||
+ | |||
+ | {{fig|2.7|Simulação Temporal de 4 FF 100ns| SIM2_4FF.png| 600 px |}} | ||
+ | |||
+ | 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. | ||
+ | * Para definir as restrições de tempo do clock por exemplo, pode ser adicionado um arquivo .sdc ao projeto definindo a frequência do clock esperada através da seguinte linha: | ||
+ | |||
+ | create_clock -name CLK50MHz -period 50MHz [get_ports {*}] | ||
+ | |||
+ | * Uso de alguns sites auxiliares para a programação em VHDL: | ||
+ | :*[[Preparando para gravar o circuito lógico no FPGA]] | ||
+ | :*[[Palavras reservadas do VHDL]] | ||
+ | :*[http://g2384.github.io/work/VHDLformatter.html VHDL Beautifier, Formatter] - para formatar automaticamente um código VHDL. | ||
+ | :*[[Media:Quartus_II_Simulation.pdf | Tutorial do QSIM - Introduction to Simulation of VHDL Designs]] da ALTERA. | ||
+ | |||
+ | *Exemplo de um contador em VHDL. [https://en.wikipedia.org/wiki/VHDL#Example:_a_counter COUNTER] na página de VHDL da Wikipedia. | ||
+ | :*[[Restringir a frequencia máxima de clock no Quartus II]] | ||
+ | |||
+ | :* Objetivos: Copiar e colar o código no Quartus; diferença entre analise e síntese e compilação; observar o RTL (usar UNGROUP); simulação funcional e simulação temporal; observar os atrasos de propagação na simulação temporal. | ||
+ | |||
+ | ;Aula 6 (23 nov): | ||
+ | * Uso das bibliotecas no VHDL. | ||
+ | :*Library '''std''' | ||
+ | ::O Package '''standard''': é parte do VHDL desde a primeira versão (1987). Ela contem definição de tipos de dados (BIT, INTEGER, BOOLEAN, CHARACTER, etc.) e seus operadores logicos, aritméticos, de comparação e shift. | ||
+ | ::O Package textio fornece os recurso para o tratamento de textos e arquivos, que podem ser utilizados na simulação. | ||
+ | *Como declarar e usar os pacotes da biblioteca '''std'''. | ||
+ | :: Note que esses pacotes são implicitamente carregados não precisando ser declarados. Ambos pacotes foram expandidos no VHDL 2008. | ||
+ | :::<syntaxhighlight lang=vhdl> | ||
+ | -- NAO É NECESSARIO DECLARAR | ||
+ | library std; | ||
+ | use std.standard.all; | ||
+ | use std.textio.all; | ||
+ | </syntaxhighlight> | ||
+ | *Onde estão os arquivos dessa biblioteca na versão Quartus II instalada nos computadores do IFSC e na IFSC_CLOUD? | ||
+ | ls /opt/altera/13.0sp1/quartus/libraries/vhdl/std | ||
+ | |||
+ | :*Library '''ieee''' | ||
+ | :: O Package '''[[Std logic 1164.vhd | std_logic_1164]]''' define os tipos de dados STD_ULOGIC e STD_LOGIC. | ||
+ | :: O Package '''[[Numeric std.vhd | numeric_std]]''' define os tipos de dados SIGNED e UNSIGNED e seus operadores considerando o tipo STD_LOGIC como base. | ||
+ | :: O Package '''numeric_bit''' define os tipos de dados SIGNED e UNSIGNED e seus operadores considerando o tipo BIT como base. | ||
+ | :: O Package '''numeric_std_unsigned''' introduz operadores sobre o tipo STD_LOGIC_VECTOR, considerando os como números sem sinal. | ||
+ | :: O Package '''numeric_bit_unsigned''' introduz operadores sobre o tipo BIT_VECTOR, considerando os como números sem sinal. | ||
+ | :: O Package '''fixed_pkg''' (e pacotes associados) definem os tipos de ponto fixo unsigned (UFIXED) e signed (SFIXED) e seus operadores. | ||
+ | :: O Package '''float_pkg''' (e pacotes associados) definem o tipo de ponto flutuante (FLOAT) e seus operadores. | ||
+ | :* Pacotes não padronizados ('''NÃO UTILIZAR''') | ||
+ | : O Package [[Std logic arith.vhd | std_logic_arith]] define os tipos de dados SIGNED e UNSIGNED e seus operadores. Deve ser sempre substituído por pelo pacote padrão equivalente numeric_std. (disponível da Mentor e Synopsys) | ||
+ | : O Package [[Std logic unsigned.vdh | std_logic_unsigned]] é semelhante ao numeric_std_unsigned. (disponível da Synopsys) | ||
+ | : O Package std_logic_signed é semelhante ao acima operando sobre números com sinal. (disponível da Synopsys) | ||
+ | |||
+ | *Como declarar e usar os pacotes da biblioteca '''ieee'''. | ||
+ | :::<syntaxhighlight lang=vhdl> | ||
+ | library ieee; | ||
+ | -- UTILIZAR ESTES PACOTES | ||
+ | use ieee.std_logic_1164.all; | ||
+ | use ieee.numeric_std.all; | ||
+ | |||
+ | -- NAO UTILIZAR ESTES PACOTES | ||
+ | use ieee.std_logic_arith.all; | ||
+ | use ieee.std_logic_signed.all; | ||
+ | use ieee.std_logic_unsigned.all; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Onde estão os arquivos dessa biblioteca na versão Quartus II versão 13.0sp1 instalada nos computadores do IFSC e na IFSC_CLOUD? | ||
+ | ::Os pacotes padrão: | ||
+ | ls /opt/altera/13.0sp1/quartus/libraries/vhdl/ieee | ||
+ | |||
+ | ::Os pacotes não padrão: | ||
+ | ls /opt/altera/13.0sp1/quartus/libraries/vhdl/mentor/arithmetic (Mentor Graphics) | ||
+ | ls /opt/altera/13.0sp1/quartus/libraries/vhdl/synopsys/ieee (Synopsys) | ||
+ | |||
+ | *Os arquivos dessa biblioteca do padrão (versão 2008) estão apenas disponíveis a partir do Quartus II versão 16.0 instalado na IFSC_CLOUD? | ||
+ | ls /opt/altera/16.0/quartus/libraries/vhdl/ieee/2008 | ||
+ | |||
+ | :* Exemplo 2.3 (VHDL e QSIM) - programação de um circuito somador com registrador | ||
+ | :: Realizar as simulações funcional e temporal do circuito | ||
+ | :: Observar o "Technology Map" e o "RTL" do circuito | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | LIBRARY ieee; | ||
+ | USE ieee.std_logic_1164.all; | ||
+ | |||
+ | ENTITY registered_comp_add IS | ||
+ | PORT (clk: IN STD_LOGIC; | ||
+ | a, b: IN INTEGER RANGE 0 TO 7; | ||
+ | reg_comp: OUT STD_LOGIC; | ||
+ | reg_sum: OUT INTEGER RANGE 0 TO 15); | ||
+ | END; | ||
+ | |||
+ | ARCHITECTURE circuit OF registered_comp_add IS | ||
+ | SIGNAL comp: STD_LOGIC; | ||
+ | SIGNAL sum: INTEGER RANGE 0 TO 15; | ||
+ | BEGIN | ||
+ | comp <= '1' WHEN a>b ELSE '0'; | ||
+ | sum <= a + b; | ||
+ | PROCESS (clk) | ||
+ | BEGIN | ||
+ | IF (clk'EVENT AND clk='1') THEN | ||
+ | reg_comp <= comp; | ||
+ | reg_sum <= sum; | ||
+ | END IF; | ||
+ | END PROCESS; | ||
+ | END; | ||
+ | </syntaxhighlight> | ||
+ | :: Acrescente saídas para o sinal '''sum''' e para o sinal '''comp''', de modo a poder observar estes sinais no simulador QSIM e realize novas simulações funcional e temporal. | ||
+ | {{fig|2.10|Código RTL do Exemplo 2.3| RTL_Ex2_3_Pedronib.png| 400 px |}} | ||
+ | |||
+ | Note que na simulação funcional a mudança da saída Q ocorre no instante em que ocorre a borda de subida do clock ou no momento do reset. No entanto, no caso da simulação com timing, existe um atraso nestas mudanças. | ||
+ | |||
+ | ''IMPORTANTE:'' Na prática normalmente não é necessário fazer a simulação temporal, pois através do Time Quest Report é possivel verificar se o circuito atende as restrições de tempo. | ||
+ | * Para definir as restrições de tempo do clock por exemplo, pode ser adicionado um arquivo .sdc ao projeto definindo a frequencia do clock esperada através da seguinte linha: | ||
+ | |||
+ | create_clock -name CLK50MHz -period 50MHz [get_ports {*}] | ||
+ | ::ver [[Media:Quartus_II_Simulation.pdf | Tutorial do QSIM - Introduction to Simulation of VHDL Designs]] da ALTERA. | ||
+ | ::Ver pag. 3 a 24 de <ref name="PEDRONI2010b"> PEDRONI, Volnei A. '''Circuit Design and Simulation with VHDL'''; 2ª ed. Massachusetts-EUA:MIT, 2010. 608 p. ISBN 9780262014335 </ref> | ||
+ | |||
+ | {{Mensagem | ||
+ | |indent = | ||
+ | |title= | ||
+ | |equation = <big> Video motivational para apreender FPGA, VHDL [https://youtu.be/ecyyZ6zTLic Microsoft's Bing* Intelligent Search with Intel® FPGAs] </big> | ||
+ | |cellpadding= 6 | ||
+ | |border | ||
+ | |border colour = #0073CF | ||
+ | |background colour=#F5FFFA}} | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 3 - Tipos de Dados e Operadores em VHDL=== | ||
+ | * 11 AULAS | ||
+ | |||
+ | {{collapse top | Unidade 3 - Tipos de Dados e Operadores em VHDL}} | ||
+ | |||
+ | ;Aula 7 (24 nov): | ||
+ | *Comentários no código (duplo traço --) | ||
+ | -- Isso eh uma linha de comentario | ||
+ | y <= a * b ; --o sinal y recebe o resultado da multiplicacao a x b | ||
+ | *Representação de caracteres, strings e números em VHDL. | ||
+ | :*Caracteres (entre aspas simples) | ||
+ | caracter: 'A' 'x' '#' (com aspas simples) | ||
+ | :*Palavras (entre aspas duplas) | ||
+ | string: "IFSC" "teste" "teste123" | ||
+ | |||
+ | :*Números em geral | ||
+ | elemento ("bit") único: '0' '1' 'Z' (entre aspas simples) | ||
+ | vetor de elementos ("bits"): "0110" "101001Z" (entre aspas duplas) | ||
+ | vetor de 1 elemento ("bit"): "0" "1" (entre aspas duplas) | ||
+ | inteiros: 5 1101 1102 (sem aspas) | ||
+ | |||
+ | :*Números binários: | ||
+ | 0 -> '0' | ||
+ | 7 (em base 2) -> "0111" ou b"0111" ou B"0111" | ||
+ | 1023 (em base 2) -> "001111111111" ou b"1111111111" ou B"1111111111" | ||
+ | |||
+ | :*Números octais: | ||
+ | 44 (em base 8) -> 5*8^1 + 4*8^0 -> O"54" ou o"54" | ||
+ | 1023 (em base 8)-> 1*8^3 + 7*8^2 + 7*8^1 + 7*8^0 -> o"1777" 8#1777# | ||
+ | |||
+ | :*Números Hexadecimais: | ||
+ | 1023 (em base 16) -> 3*16^2 + 15*16^1 + 15*16^0 = X"3FF" ou x"3FF" 16#3FF# | ||
+ | |||
+ | :*Números decimais: | ||
+ | 1023 -> 1023 ou 1_023 | ||
+ | 1000 -> 1000 ou 1_000 ou 1E3 | ||
+ | ::Cuidado ao usar o "_" pois algumas ferramentas não o reconhecem. | ||
+ | |||
+ | :*Números em outras bases (de 2 a 16) | ||
+ | 85 (em base 5) -> (3*5^2 + 2*5^1 + 0*5^0) -> 5#320# | ||
+ | 1539 (em base 3) -> (2*3^2+0*3^1+1*3^0)*3^4 -> 3#201#E4 | ||
+ | |||
+ | *Tipos de dados em VHDL. | ||
+ | :*Objetos de VHDL: '''CONSTANT''', '''SIGNAL''', '''VARIABLE''', '''FILE'''. | ||
+ | |||
+ | <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''''') | ||
+ | |||
+ | * Classificação dos tipos de dados. | ||
+ | |||
+ | A biblioteca [[standard.vhd]] define os tipos BIT, BIT_VECTOR, BOOLEAN, INTEGER, NATURAL, POSITIVE, CHARACTER, STRING. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | package standard is | ||
+ | type boolean is (false,true); | ||
+ | type bit is ('0', '1'); | ||
+ | type severity_level is (note, warning, error, failure); | ||
+ | type integer is range -2147483647 to 2147483647; | ||
+ | type real is range -1.0E308 to 1.0E308; | ||
+ | type time is range -2147483648 to 2147483647 | ||
+ | units | ||
+ | fs; | ||
+ | ps = 1000 fs; | ||
+ | ns = 1000 ps; | ||
+ | us = 1000 ns; | ||
+ | ms = 1000 us; | ||
+ | sec = 1000 ms; | ||
+ | min = 60 sec; | ||
+ | hr = 60 min; | ||
+ | end units; | ||
+ | subtype natural is integer range 0 to integer'high; | ||
+ | subtype positive is integer range 1 to integer'high; | ||
+ | type string is array (positive range <>) of character; | ||
+ | type bit_vector is array (natural range <>) of bit; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A biblioteca [[Std logic 1164.vhd]] define os tipos STD_(U)LOGIG, STD_(U)LOGIG_VECTOR. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | PACKAGE std_logic_1164 IS | ||
+ | TYPE std_ulogic IS ( 'U', -- Uninitialized | ||
+ | 'X', -- Forcing Unknown | ||
+ | '0', -- Forcing 0 | ||
+ | '1', -- Forcing 1 | ||
+ | 'Z', -- High Impedance | ||
+ | 'W', -- Weak Unknown | ||
+ | 'L', -- Weak 0 | ||
+ | 'H', -- Weak 1 | ||
+ | '-' -- Don't care | ||
+ | ); | ||
+ | TYPE std_ulogic_vector IS ARRAY ( NATURAL RANGE <> ) OF std_ulogic; | ||
+ | SUBTYPE std_logic IS resolved std_ulogic; | ||
+ | TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A biblioteca [[Std logic 1164.vhd]] ainda define algumas funções importantes como a '''rising_edge''' que determina se um sinal está na borda de subida (usado em sinais de clock). | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ------------------------------------------------------------------- | ||
+ | -- conversion functions | ||
+ | ------------------------------------------------------------------- | ||
+ | FUNCTION To_bit ( s : std_ulogic; xmap : BIT := '0') RETURN BIT; | ||
+ | FUNCTION To_bitvector ( s : std_logic_vector ; xmap : BIT := '0') RETURN BIT_VECTOR; | ||
+ | FUNCTION To_StdULogic ( b : BIT ) RETURN std_ulogic; | ||
+ | FUNCTION To_StdLogicVector ( b : BIT_VECTOR ) RETURN std_logic_vector; | ||
+ | |||
+ | ------------------------------------------------------------------- | ||
+ | -- edge detection | ||
+ | ------------------------------------------------------------------- | ||
+ | FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN; | ||
+ | FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN; | ||
+ | |||
+ | ------------------------------------------------------------------- | ||
+ | -- edge detection | ||
+ | ------------------------------------------------------------------- | ||
+ | FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS | ||
+ | -- altera built_in builtin_rising_edge | ||
+ | BEGIN | ||
+ | RETURN (s'EVENT AND (To_X01(s) = '1') AND | ||
+ | (To_X01(s'LAST_VALUE) = '0')); | ||
+ | END; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | A biblioteca [[Numeric std.vhd]] define os tipos UNSIGNED e SIGNED. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | package NUMERIC_STD is | ||
+ | type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; | ||
+ | type SIGNED is array (NATURAL range <>) of STD_LOGIC; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A biblioteca [[Numeric std.vhd]] ainda define os operadores (abs, "+", "-", "*", "\", rem, mod, sll, slr, ror, rol), comparações ("=", '/=', ">", ">=", "<", "<=") e operadores lógicos (not, and, nand, or, nor, xor, xnor) para os tipos SIGNED e UNSIGNED. Além disso também define algumas funções muito utilizadas como: | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --============================================================================ | ||
+ | -- RESIZE Functions | ||
+ | --============================================================================ | ||
+ | function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED; | ||
+ | function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED; | ||
+ | |||
+ | --============================================================================ | ||
+ | -- Conversion Functions | ||
+ | --============================================================================ | ||
+ | function TO_INTEGER (ARG: UNSIGNED) return NATURAL; | ||
+ | function TO_INTEGER (ARG: SIGNED) return INTEGER; | ||
+ | function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED; | ||
+ | function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* Resumo dos Tipos predefinidos. | ||
+ | {| class="wikitable sortable" border="1" cellpadding="3" cellspacing="0" style="text-align:left; font-size:100%" bgcolor="#efefef" | ||
+ | ! scope="col" width=15% align="left"| Tipo de Dado | ||
+ | ! scope="col" width=10% align="left"| Package | ||
+ | ! scope="col" width=7% align="left"| Library | ||
+ | ! scope="col" width=50% align="left"| Valores | ||
+ | ! scope="col" width=15% align="left"| Observações | ||
+ | |- | ||
+ | | BOOLEAN || standard || std || TRUE e FALSE || sintetizável | ||
+ | |- | ||
+ | | BIT || standard || std || valores '0', '1' || sintetizável | ||
+ | |- | ||
+ | | INTEGER || standard || std || números inteiros de 32 bits [de -2^31 até + (2^31 - 1)] || sintetizável | ||
+ | |- | ||
+ | | NATURAL || standard || std || números inteiros não negativos [de 0 até + (2^31 - 1)] || sintetizável | ||
+ | |- | ||
+ | | POSITIVE || standard || std || números inteiros positivos [de 1 até + (2^31 - 1)] || sintetizável | ||
+ | |- | ||
+ | | BOOLEAN_VECTOR || standard (2008) || std || vetor de BOOLEAN || sintetizável | ||
+ | |- | ||
+ | | BIT_VECTOR || standard || std || vetor de BIT || sintetizável | ||
+ | |- | ||
+ | | INTEGER_VECTOR || standard || std || vetor de INTEGER || sintetizável | ||
+ | |- | ||
+ | | REAL || standard || std || números reais [de -1.0E-38 até + 1.0E38] || simulação | ||
+ | |- | ||
+ | | CHARACTER || standard || std || caracteres ASCII || | ||
+ | |- | ||
+ | | STRING || standard || std || vetor de CHARACTER || | ||
+ | |- | ||
+ | | STD_LOGIC || std_logic_1164 || ieee || valores 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-' || sintetizável | ||
+ | |- | ||
+ | | STD_LOGIC_VECTOR || std_logic_1164 || ieee || vetor de STD_LOGIC || sintetizável | ||
+ | |- | ||
+ | | SIGNED || numeric_std || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas com sinal|| sintetizável | ||
+ | |- | ||
+ | | UNSIGNED || numeric_std || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas sem sinal || sintetizável | ||
+ | |- | ||
+ | | SIGNED || numeric_bit || ieee || BIT_VECTOR que aceitam operações aritméticas com sinal || sintetizável | ||
+ | |- | ||
+ | | UNSIGNED || numeric_bit || ieee || BIT_VECTOR que aceitam operações aritméticas sem sinal || sintetizável | ||
+ | |- | ||
+ | | SIGNED || std_logic_arith || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas com sinal || sintetizável (não é padrão, não utilizar) | ||
+ | |- | ||
+ | | UNSIGNED || std_logic_arith || ieee || STD_LOGIC_VECTOR que aceitam operações aritméticas sem sinal || sintetizável (não é padrão, não utilizar) | ||
+ | |- | ||
+ | | UFIXED || fixed_pkg + (2008) || ieee || números de ponto fixo sem sinal|| sintetizável | ||
+ | |- | ||
+ | | SFIXED || fixed_pkg + (2008) || ieee || números de ponto fixo com sinal|| sintetizável | ||
+ | |- | ||
+ | | FLOAT || float_pkg + (2008) || ieee || Números de ponto flutuante || sintetizável | ||
+ | |} | ||
+ | |||
+ | :* Tipos de dados predefinidos: FIXED e FLOAT (apenas conhecer) | ||
+ | * '''Desafio''' - Fazer um circuito que detecte se existe alguma vaga vazia em um lote de 5 vagas. A entrada x(n) está baixo '0' se a vaga está vazia, e alto '1' se tem carro. A saída y estará alta '1' sempre que houver uma ou mais vagas vazias, e em baixo '0' se não houver nenhuma vaga. | ||
+ | |||
+ | *Faça a simulação do circuito para ver se está funcionando, | ||
+ | {{fig|3.1| Simulação do indicador de vagas | vagas5.png | 800 px |}} | ||
+ | |||
+ | :: Ver função resize | ||
+ | :: Ver pag. 73 a 78 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | |||
+ | ;Aula 8 (26 nov): | ||
+ | |||
+ | * Exemplo 3.1 Buffer Tri-state | ||
+ | :*Ver como funciona em [http://bibl.ica.jku.at/dc/build/html/basiccircuits/basiccircuits.html#figure-1] | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | |||
+ | entity tri_state is | ||
+ | generic (N: NATURAL := 1); | ||
+ | port | ||
+ | ( | ||
+ | input : in std_logic_vector(N-1 downto 0); | ||
+ | ena : in std_logic; | ||
+ | output : out std_logic_vector(N-1 downto 0); | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture tri_state of tri_state is | ||
+ | begin | ||
+ | output <= input when ena = '1' else "Z"; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::* Corrija os erros do código e verifique o modelo RTL obtido. | ||
+ | ::* Em seguida modifique as portas '''input''' e '''output''' para o tipo '''std_logic'''. | ||
+ | ::* Analise se seria possível modificar as portas para o tipo '''bit'''. | ||
+ | :: '''Importante''': O terceiro estado 'Z' só pode ser usado em saídas, e a sua realização nos FPGAs só ocorre nos nós de I/O. | ||
+ | |||
+ | :* Exemplo 3.2 Circuito com Saida "don't care" | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | |||
+ | entity Ex3_2 is | ||
+ | port | ||
+ | ( | ||
+ | x : in STD_LOGIC_VECTOR(1 downto 0); | ||
+ | y : out STD_LOGIC_VECTOR(1 downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture un3 of Ex3_2 is | ||
+ | begin | ||
+ | y <= "00" when x = "00" else | ||
+ | "01" when x = "10" else | ||
+ | "10" when x = "01" else | ||
+ | "--"; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Inspirado na descrição VHDL acima, tente resolver o '''Desafio ''' - Fazer um circuito que detecte se existe alguma vaga vazia em um lote de 5 vagas. Cada entrada x(n) está baixo '0' se a vaga está vazia. A saída y estará alta '1' sempre que houver uma ou mais vagas vazias. | ||
+ | :'''Importante''': O ''don't care'' não funciona como se espera para uma entrada, por isso, use ''don't care'' apenas para saídas. | ||
+ | x = "1----" -- não funciona em VHDL | ||
+ | *Se quiser mesmo usar ''don't care'' em entradas use a função '''std_match''' do pacote '''numeric_std''' | ||
+ | std_match(x, "1----") -- funciona em VHDL | ||
+ | |||
+ | |||
+ | ;Aula 9 (30 nov): | ||
+ | :* Tipos de dados: SIGNED e UNSIGNED | ||
+ | |||
+ | :* Exemplo 3.3 Multiplicador de 4x4 bits (UN)SIGNED e INTEGER | ||
+ | |||
+ | {{collapse top | expand=true| Código Multiplicador}} | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --LIBRARY ieee; | ||
+ | --USE ieee.numeric_std.all; | ||
+ | --USE ieee.std_logic_1164.all; | ||
+ | |||
+ | ENTITY multiplicador4x4 IS | ||
+ | |||
+ | -- multiplicador usando INTEGER (positivos) | ||
+ | -- PORT (a, b: IN INTEGER RANGE 0 TO 15; -- min(a) = 0; max(a) = 15 -> 4 bits | ||
+ | -- y: OUT INTEGER RANGE 0 TO 225); -- min(a*b) = 0, max(a*b) = 225 -> 8 bits | ||
+ | |||
+ | -- multiplicador usando INTEGER (positivos e negativos) | ||
+ | -- PORT (a, b: IN INTEGER RANGE -8 TO 7; -- min(a) = -8; max(a) = 7 -> 4 bits | ||
+ | -- y: OUT INTEGER RANGE -56 TO 64); -- min(a*b) = -56, max(a*b) = 64 -> 8 bits | ||
+ | |||
+ | -- multiplicador usando UNSIGNED | ||
+ | -- PORT (a, b: IN UNSIGNED(3 DOWNTO 0); -- min(a) = 0; max(a) = 15 <- 4 bits | ||
+ | -- y: OUT UNSIGNED(7 DOWNTO 0)); -- min(a*b) = 0, max(a*b) = 225 -> 8 bits | ||
+ | |||
+ | -- multiplicador usando SIGNED | ||
+ | -- PORT (a, b: IN SIGNED(3 DOWNTO 0); -- min(a) = -8; max(a) = 7 <- 4 bits | ||
+ | -- y: OUT SIGNED(7 DOWNTO 0)); -- min(a*b) = -56, max(a*b) = 64 -> 8 bits | ||
+ | |||
+ | |||
+ | -- multiplicador usando STD_LOGIC_VECTOR | ||
+ | -- PORT (a, b: IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- min(a) = 0; max(a) = 15 <- 4 bits | ||
+ | -- y: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); -- min(a*b) = 0, max(a*b) = 225 -> 8 bits | ||
+ | |||
+ | -- multiplicador usando STD_LOGIC_VECTOR | ||
+ | -- PORT (a, b: STD_LOGIC_VECTOR(3 DOWNTO 0); -- min(a) = -8; max(a) = 7 <- 4 bits | ||
+ | -- y: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); -- min(a*b) = -56, max(a*b) = 64 -> 8 bits | ||
+ | |||
+ | |||
+ | END ENTITY; | ||
+ | |||
+ | ARCHITECTURE v1 OF multiplicador4x4 IS | ||
+ | BEGIN | ||
+ | y <= a * b; | ||
+ | END ARCHITECTURE; | ||
+ | </syntaxhighlight> | ||
+ | *Observar o número de elementos lógicos, bits usados para representar as entradas e saídas. | ||
+ | *Observar o código RTL obtido. | ||
+ | *Realizar a simulação com entradas UNSIGNED e INTEGER na faixa de valores de 0 até 15, e analisar se o valor da saída está correto. | ||
+ | *Realizar a simulação com entradas SIGNED e INTEGER na faixa de valores de -8 até 7, e analisar se o valor da saída está correto. | ||
+ | *Realizar a simulação com entradas STD_LOGIC_VECTOR na faixa de valores de 0 até 15, e analisar se o valor da saída está correto. Neste caso será necessário realizar uma conversão de STD_LOGIC_VECTOR para UNSIGNED antes de efetuar a operação de "*", e após a operação é necessário fazer a operação inversa UNSIGNED para STD_LOGIC_VECTOR | ||
+ | *Realizar a simulação com entradas STD_LOGIC_VECTOR na faixa de valores de -8 até 7, e analisar se o valor da saída está correto. Neste caso será necessário realizar uma conversão de STD_LOGIC_VECTOR para SIGNED antes de efetuar a operação de "*", e após a operação é necessário fazer a operação inversa SIGNED para STD_LOGIC_VECTOR | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | <center> | ||
+ | {{Mensagem | ||
+ | |indent = | ||
+ | |title= | ||
+ | |equation = <big> Ler e guardar a página sobre [[Aritmética com vetores em VDHL]] </big> | ||
+ | |cellpadding= 6 | ||
+ | |border | ||
+ | |border colour = #0073CF | ||
+ | |background colour=#F5FFFA}} | ||
+ | </center> | ||
+ | |||
+ | :: Ver pag. 39 a 54 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;Aula 10 (3 dez): | ||
+ | *Operadores em VHDL. | ||
+ | :* Operadores predefinidos: Atribuição, Lógicos, Aritméticos, Comparação, Deslocamento, Concatenação, "Matching". | ||
+ | ;Operadores lógicos: | ||
+ | São suportados nos tipos de dados: BIT, BIT_VECTOR, BOOLEAN, STD_(U)LOGIC, STD_(U)LOGIC_VECTOR, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para BOOLEAN_VECTOR, UFIXED, SFIXED e FLOAT. | ||
+ | |||
+ | NOT | ||
+ | AND | ||
+ | NAND | ||
+ | OR | ||
+ | NOR | ||
+ | XOR | ||
+ | XNOR | ||
+ | |||
+ | Apenas o operador NOT tem precedência sobre os demais | ||
+ | y <= a AND b XOR c -- é equivalente a (a AND b) XOR c | ||
+ | y <= NOT a AND b -- é equivalente a (NOT a) AND b. | ||
+ | y <= a NAND b -- é equivalente a NOT (a AND b) | ||
+ | |||
+ | |||
+ | |||
+ | ;Operadores aritméticos: | ||
+ | São suportados nos tipos de dados: INTEGER, NATURAL, POSITIVE, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para UFIXED, SFIXED e FLOAT. | ||
+ | |||
+ | soma (+) | ||
+ | subtração (-) | ||
+ | multiplicação (*) | ||
+ | divisão (/) | ||
+ | exponenciação (**) | ||
+ | valor absoluto (ABS) | ||
+ | resto (REM ''remainder'') | ||
+ | módulo (MOD) | ||
+ | |||
+ | Não há restrições para síntese de circuitos com os operadores, exceto para '''"**"''' que necessita de expoente estático ('''a**5''') ou base estática ('''5**a'''). | ||
+ | |||
+ | O operador '''x/y''' é a divisão inteira com sinal. | ||
+ | :Exemplos: 9/10 = 0; -7/3 = -2; 9/-4 = -2; 20/(-4) = -5. | ||
+ | |||
+ | O operador '''ABS x''' retorna o valor absoluto de x. | ||
+ | :Exemplos: ABS 6 = 6; ABS -11 = 11. | ||
+ | |||
+ | O operador '''x REM y''' retorna o resto de '''x/y''' com sinal de '''x'''. Esse operador realiza a operação '''x REM y = x - (x/y)*y'''. | ||
+ | :Exemplos: 9 REM 10 = 9; -7 REM 3 = -1; 9 REM -4 = 1; 20 REM (-4) = 0. | ||
+ | |||
+ | O operador '''x MOD y''' retorna o resto de '''x/y''' com sinal de '''y'''. Esse operador realiza a operação '''x MOD y = x REM y + a*y''', onde '''a = 1''' quando o sinal de x é diferente do sinal de y, e '''a = 0''' se os sinais de x e y são iguais. | ||
+ | :Exemplos: 9 MOD 10 = 9 REM 10 = 9; -7 MOD 3 = 2; 9 REM -4 = -3; 20 REM (-4) = 0. | ||
+ | |||
+ | |||
+ | :: Ver pag. 91 a 97 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;Exemplo de uso de operadores aritméticos: | ||
+ | :* Exemplo conversor de binário para [[BCD - Binary-coded decimal]] de dois dígitos decimais (00 a 99). Para ilustrar são utilizadas os operadores DIVISOR e RESTO. Note a quantidade de elementos lógicos utilizados. É possível reduzir essa quantidade, aproveitando resultados intermediários e evitando a realização de uma nova divisão pelo uso do operador REM. Faça uma segunda implementação que reduza significativamente o número de elementos lógicos. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | use ieee.numeric_std.all; | ||
+ | |||
+ | entity bin2bcd is | ||
+ | port | ||
+ | ( | ||
+ | |||
+ | C : in std_logic_vector (6 downto 0); | ||
+ | sd, su : out std_logic_vector (3 downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ifsc_v1 of bin2bcd is | ||
+ | signal C_uns : unsigned (6 downto 0); | ||
+ | signal sd_uns, su_uns : unsigned (6 downto 0); | ||
+ | begin | ||
+ | sd <= std_logic_vector(resize(sd_uns, 4)); | ||
+ | su <= std_logic_vector(resize(su_uns, 4)); | ||
+ | sd_uns <= C_uns/10; | ||
+ | su_uns <= C_uns rem 10; | ||
+ | c_uns <= unsigned(c); | ||
+ | end architecture; | ||
+ | |||
+ | architecture ifsc_v2 of bin2bcd is | ||
+ | |||
+ | begin | ||
+ | -- Implemente o circuito usando a definição de REM que é: x REM y = x - (x/y)*y | ||
+ | end architecture; | ||
+ | |||
+ | configuration bin2bcd_cfg of bin2bcd is | ||
+ | --A instrução '''configuration''' associa a '''entity''' bin2bcd a '''architecture'''. | ||
+ | for ifsc_v1 end for; | ||
+ | --Para associar a '''entity''' bin2bcd a '''architecture''' ifsc_v2 comente a linha acima e descomente a linha abaixo. | ||
+ | -- for ifsc_v2 end for; | ||
+ | end configuration; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {{fig|3.2| RTL do conversor de Binário para BCD com 2 digitos | bin2bcdDU_RTL.png | 600 px |}} | ||
+ | |||
+ | {{fig|3.3| Simulação do conversor de Binário para BCD com 2 digitos | bin2bcdDU_modelsim.png | 1000 px |}} | ||
+ | |||
+ | ;Aula 11 e 12 (7 e 8 dez): | ||
+ | Atributos em VHDL. | ||
+ | * Atributos de síntese: | ||
+ | Em VHDL existem diversos atributos de sintese que controlam a forma como o processo de "Analysis & Synthesis" é realizado pelo Quartus II. Uma listagem completa pode ser encontrada em: | ||
+ | *[https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir.htm VHDL Synthesis Attributes and Directives] - Quartus Prime Pro Edition Help version 18.1 | ||
+ | |||
+ | :* '''ATTRIBUTE enum_encoding''' [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_enum_encoding.htm] | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | type fruit is (apple, orange, pear, mango); | ||
+ | attribute enum_encoding : string; | ||
+ | attribute enum_encoding of fruit : type is "11 01 10 00"; | ||
+ | </syntaxhighlight> | ||
+ | :* '''ATTRIBUTE chip_pin''' [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_chip.htm] | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity foo is | ||
+ | port (sel : in std_logic; | ||
+ | data : in std_logic_vector(3 downto 0); | ||
+ | o : out std_logic); | ||
+ | end foo; | ||
+ | architecture rtl of foo is | ||
+ | |||
+ | attribute chip_pin : string; | ||
+ | attribute chip_pin of sel : signal is "C4"; | ||
+ | attribute chip_pin of data : signal is "D1, D2, D3, D4"; | ||
+ | begin | ||
+ | -- Specify additional code | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | <i> | ||
+ | O uso desse atributo sobrepõe a atribuição dos pinos através da IDE do Quartus II, e por isso não é recomendável. | ||
+ | |||
+ | O atributo de síntese chip_pin pode ser usado apenas em portas da entidade "top-level" do projeto. . | ||
+ | </i> | ||
+ | |||
+ | :* '''ATTRIBUTE keep''' [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_keep.htm] | ||
+ | O atributo de síntese KEEP, sinaliza ao processo de "Analysis & Synthesis" para manter intacto um determinado signal ou componente. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | signal a,b,c : std_logic; | ||
+ | attribute keep: boolean; | ||
+ | attribute keep of a,b,c: signal is true; | ||
+ | </syntaxhighlight> | ||
+ | ::* Exemplo 4.4: Delay line (Síntese e Simulação temporal sem o com o atributo keep) | ||
+ | ::* Exemplo 5.8 Gerador de Pulsos estreitos | ||
+ | ::* '''ATTRIBUTE preserve''' [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_preserve.htm], [https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#logicops/logicops/def_preserve_fanout_free_node.htm]. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | signal a,b,c : std_logic; | ||
+ | attribute preserve: boolean; | ||
+ | attribute preserve of a,b,c: signal is true; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* '''ATTRIBUTE noprune'''[https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir_noprune.htm]. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | signal reg1: std_logic; | ||
+ | attribute noprune: boolean; | ||
+ | attribute noprune of reg1: signal is true; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exemplo 4.5: Registros redundantes}} | ||
+ | Síntese sem e com os atributos keep, preserve e noprune | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ENTITY redundant_registers IS | ||
+ | PORT ( | ||
+ | clk, x: IN BIT; | ||
+ | y: OUT BIT); | ||
+ | END ENTITY; | ||
+ | |||
+ | ARCHITECTURE arch OF redundant_registers IS | ||
+ | SIGNAL a, b, c: BIT; | ||
+ | -- NORMAL -- 1 LE | ||
+ | --ATTRIBUTE preserve: BOOLEAN; | ||
+ | --ATTRIBUTE preserve OF a, b, c: SIGNAL IS TRUE; -- 2 LE | ||
+ | --ATTRIBUTE noprune: BOOLEAN; | ||
+ | --ATTRIBUTE noprune OF a, b, c: SIGNAL IS TRUE; --3 LE | ||
+ | --ATTRIBUTE keep: BOOLEAN; | ||
+ | --ATTRIBUTE keep of a,b,c: SIGNAL IS TRUE; | ||
+ | BEGIN | ||
+ | PROCESS (clk) | ||
+ | BEGIN | ||
+ | IF (clk'EVENT AND clk='1') THEN | ||
+ | a <= x; | ||
+ | b <= x; | ||
+ | c <= x; | ||
+ | END IF; | ||
+ | END PROCESS; | ||
+ | y <= a AND b; | ||
+ | END ARCHITECTURE; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Após a compilação do código acima, observe o número de elementos lógicos obtidos, observe o '''Technology Map''' dos circuitos gerados e verifique a localização dos FFs no '''Chip Planner'''. | ||
+ | {{fig|3.4| Technology Map do circuito compilado sem Attribute | Ex4_5_NoAttribute.png | 400 px |}} | ||
+ | |||
+ | {{fig|3.5| Technology Map do Circuito com Attribute Preserve (or Keep) | Ex4_5_PreserveAttribute.png | 400 px |}} | ||
+ | |||
+ | {{fig|3.6| Technology Map do Circuito com Attribute Noprune | Ex4_5_NopruneAttribute.png | 400 px |}} | ||
+ | |||
+ | :: Ver pag. 91 a 111 de <ref name="PEDRONI2010b"/> | ||
+ | {{collapse bottom}} | ||
+ | * Operadores de deslocamento (SHIFT) | ||
+ | :*SLL (''Shift Left Logic'') - Deslocamento a esquerda lógico (preenchimento com '0's das posições a direita. | ||
+ | :*SRL (''Shift Right Logic'') - Deslocamento a direita lógico (preenchimento com '0's das posições a esquerda. | ||
+ | :*SLA (''Shift Left Arithmetic'') - Deslocamento a esquerda aritmético (posições liberadas da direita mantém o bit lsb) | ||
+ | :*SRA (''Shift Right Arithmetic'') - Deslocamento a esquerda aritmético (posições liberadas da esquerda mantém o bit msb) | ||
+ | :*ROL (''Rotate Left'') - Deslocamento circular a esquerda ( o bit que sai na esquerda é retornado na direita) | ||
+ | :*ROR (''Rotate Right'') - Deslocamento circular a direita ( o bit que sai na direita é retornado na esquerda) | ||
+ | |||
+ | signal a: bit_vector(7 downto 0) := "01100101"; | ||
+ | y <= a SLL 2; -- y <= "100101'''00'''" (y <= a(5 downto 0) & "00";) | ||
+ | y <= a SLA 2; -- y <= "100101'''11'''" (y <= a(5 downto 0) & a(0) & a(0);) | ||
+ | y <= a ROR 2; -- y <= "'''01'''011001" (y <= a(1 downto 0) & a(7 downto 2);) | ||
+ | |||
+ | ::Esses operadores são suportados nos tipos BIT_VECTOR, (UN)SIGNED. Em VHDL 2008 também para BOOLEAN_VECTOR, STD_(U)LOGIG_VECTOR, UFIXED e SFIXED. | ||
+ | |||
+ | * Operador de concatenação ('''&''') | ||
+ | ::Esse operador é suportado nos tipos BIT_VECTOR, STD_(U)LOGIG_VECTOR, STRING e (UN)SIGNED. Em VHDL 2008 também para INTEGER_VECTOR e BOOLEAN_VECTOR. | ||
+ | ::É utilizado para agrupar objetos como mostrado nos comentários dos exemplos anteriores | ||
+ | |||
+ | *Operadores de comparação | ||
+ | ::São suportados nos tipos de dados: BIT, BIT_VECTOR, BOOLEAN, INTEGER, NATURAL, POSITIVE, CHARACTER, STRING, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para BOOLEAN_VECTOR, INTEGER_VECTOR, UFIXED, SFIXED e FLOAT. | ||
+ | Igualdade (=) | ||
+ | Diferença (/=) | ||
+ | Menor que (<) | ||
+ | Menor ou igual que (<=) | ||
+ | Maior que (>) | ||
+ | Maior ou igual que (>=) | ||
+ | |||
+ | *Operadores de comparação de associação (''matching comparison'') | ||
+ | ::Foram introduzidos no VHDL 2008, e tem o objetivo de tratar nos tipos baseados no STD_ULOGIC de forma igual os valores lógicos 'H'='1' e também 'L'='0', e 'X'='Z'='W'. São suportados nos tipos de dados: BIT, BIT_VECTOR, STD_(U)LOGIG, STD_(U)LOGIG_VECTOR, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para UFIXED, SFIXED. | ||
+ | Igualdade (?=) | ||
+ | Diferença (?/=) | ||
+ | Menor que (?<) | ||
+ | Menor ou igual que (?<=) | ||
+ | Maior que (?>) | ||
+ | Maior ou igual que (?>=) | ||
+ | |||
+ | |||
+ | ;Aula 13 (10 dez): | ||
+ | * Atributos predefinidos são definidos no padrão [https://ieeexplore-ieee-org.ez130.periodicos.capes.gov.br/stamp/stamp.jsp?tp=&arnumber=8938196 1076-2019 - IEEE Standard for VHDL Language Reference Manual]. Esse documento pode ser acesso via o portal Periódicos Capes acesso CAFE. | ||
+ | Para cada atributo existe uma descrição completa como mostrado a seguir. | ||
+ | P'LEFT Kind: Value. | ||
+ | Prefix: Any prefix P that is appropriate for an object with a scalar type or subtype T, or an alias thereof, or that denotes any scalar type or subtype T. | ||
+ | Result type: Same type as T. | ||
+ | Result: The left bound of T. | ||
+ | A seguir estão listados alguns dos atributos mais utilizados. | ||
+ | |||
+ | :*16.2.2 Predefined attributes of types and objects (p.270) | ||
+ | P'LEFT - The left bound of T. | ||
+ | P'RIGHT - The right bound of T. | ||
+ | P'HIGH - The upper bound of T. | ||
+ | P'LOW - The lower bound of T. | ||
+ | P'ASCENDING - It is TRUE if T is defined with an ascending range; FALSE otherwise. | ||
+ | P'LENGTH - maximum(0, T’POS(T’HIGH) – T’POS(T’LOW) + 1) | ||
+ | P'RANGE - The range T'LEFT to T'RIGHT if the range of T is ascending, or the range T'LEFT downto T'RIGHT if the range of T is descending | ||
+ | P'REVERSE_RANGE - The range T'RIGHT downto T'LEFT if the range of T is ascending, or the range T'RIGHT to T'LEFT if the range of T is descending | ||
+ | T'POS(X) - The position number of the value of the parameter | ||
+ | T'VAL(X) - The value whose position number is the universal_integer value corresponding to X. | ||
+ | |||
+ | :*16.2.3 Predefined attributes of arrays (p.275) | ||
+ | A'LEFT [(N)] - Left bound of the Nth index range of A | ||
+ | A'RIGHT [(N)] - Right bound of the Nth index range of A | ||
+ | A'HIGH [(N)] - Upper bound of the Nth index range of A | ||
+ | A'LOW [(N)] - Lower bound of the Nth index range of A. | ||
+ | A'RANGE [(N)] - The range A'LEFT(N) to A'RIGHT(N) if the Nth index range of A is ascending, or the range A'LEFT(N) downto A'RIGHT(N) if the Nth index range of A is descending | ||
+ | A'REVERSE_RANGE [(N)] - The range A'RIGHT(N) downto A'LEFT(N) if the Nth index range of A is ascending, or the range A'RIGHT(N) to A'LEFT(N) if the Nth index range of A is descending. | ||
+ | A'LENGTH [(N)] - Number of values in the Nth index range | ||
+ | A'ASCENDING [(N)] - TRUE if the Nth index range of A is defined with an ascending range; FALSE otherwise. | ||
+ | |||
+ | :*16.2.4 Predefined attributes of signals (p. 277) | ||
+ | S'EVENT - A value that indicates whether an event has just occurred on signal S. | ||
+ | S'LAST_VALUE - For a signal S, if an event has occurred on S in any simulation cycle, S'LAST_VALUE returns the value of S prior to the update of S in the last simulation cycle in which an event occurred; otherwise, S'LAST_VALUE returns the current value of S. | ||
+ | |||
+ | :*16.2.5 Predefined attributes of named entities (p. 279) | ||
+ | E'SIMPLE_NAME - The simple name, character literal, or operator symbol of the named entity | ||
+ | |||
+ | * Atributos definidos pelo usuário; | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | attribute attribute_name: attribute_type; | ||
+ | attribute attribute_name of entity_tag [signature]: entity_class is value; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | ;Aula 14 (14 dez): | ||
+ | :* Tipos definidos pelo usuário: | ||
+ | ::* Escalares (Inteiros e Enumerados) | ||
+ | ::* Tipos de Array 1D x 1D, 2D , 1D x 1D x 1D, 3D. Ver : [[Array em VHDL]] | ||
+ | |||
+ | |||
+ | ;Aula 15 (17 dez): | ||
+ | {{collapse top| bg=lightyellow | Exemplo 3.5: Array de Integers 1D x 1D}} | ||
+ | O código abaixo cria um '''array''' de inteiros e utiliza as entradas "row" para fazer a leitura dos dados em uma tabela declarada como '''constant'''. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity array_1Dx1D_integer is | ||
+ | port ( | ||
+ | row : in integer range 1 to 3; | ||
+ | slice : out integer range 0 to 15 | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture teste of array_1Dx1D_integer is | ||
+ | type a1Dx1D_integer is array (1 to 3) of integer range 0 to 15; | ||
+ | constant table : a1Dx1D_integer := (15, 5, 7); | ||
+ | begin | ||
+ | slice <= table(row); | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | Responda as seguintes perguntas: | ||
+ | :1) Faça um desenho que represente o ARRAY declarado acima. | ||
+ | :2) Quantos bits são necessários para representar esse ARRAY? | ||
+ | :3) Qual o valor na saída quando a entrada row = 2? | ||
+ | :4) Quantos elementos lógicos são necessários para fazer a síntese deste circuito? | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exemplo 3.6: Array de bits 1D x 1D }} | ||
+ | O código abaixo cria um '''array''' de bits e utiliza as entradas "row" e "column" para fazer a leitura dos dados em uma tabela declarada como '''constant'''. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | |||
+ | entity array_1Dx1D_bit is | ||
+ | port ( | ||
+ | row : in integer range 1 to 3; | ||
+ | column : in integer range 0 to 4; --3 bits | ||
+ | slice1 : out bit; | ||
+ | slice2 : out bit_vector(1 to 2); | ||
+ | slice3 : out bit_vector(1 to 4); | ||
+ | slice4 : out bit_vector(1 to 3) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture teste of array_1Dx1D_bit is | ||
+ | type a1Dx1D_bit is array (1 to 3) of bit_vector(1 to 4); | ||
+ | constant table : a1Dx1D_bit := | ||
+ | (('1', '1', '1', '1'), --15 | ||
+ | ('0', '1', '0', '1'), -- 5 | ||
+ | ('0', '1', '1', '1')); -- 7 | ||
+ | begin | ||
+ | --slice1 <= table(row)(column); | ||
+ | --slice2 <= table(row)(1 to 2); | ||
+ | --slice3 <= table(row)(1 to 4); | ||
+ | --slice4 <= table(1 TO 3)(column); | ||
+ | --slice4 <= table(1)(column) & table(2)(column) & table(3)(column); | ||
+ | |||
+ | --gen : for i in 1 to 3 generate | ||
+ | -- slice4(i) <= table(i)(column); | ||
+ | --end generate; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | Responda as seguintes perguntas: | ||
+ | :1) Faça um desenho que represente o ARRAY declarado acima. | ||
+ | :2) Quantos bits são necessários para representar esse ARRAY? | ||
+ | :3) Descomente uma a uma as linhas na architecture. Verifique quais são aceitas pelo compilador? As 3 últimas formam um bloco único | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exemplo 3.7: Array de bits 2D }} | ||
+ | O código abaixo cria um '''array''' de bits e utiliza as entradas "row" e "column" para fazer a leitura dos dados em uma tabela declarada como '''constant'''. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity array_2D_bits is | ||
+ | port ( | ||
+ | row : in integer range 0 to 3; | ||
+ | column : in integer range 0 to 4; --3 bits | ||
+ | slice1 : out bit; | ||
+ | slice2 : out BIT_VECTOR(1 to 2); | ||
+ | slice3 : out BIT_VECTOR(1 to 4); | ||
+ | slice4 : out BIT_VECTOR(1 to 3) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture teste of array_2D_bits is | ||
+ | type a2D_bits is array (1 to 3, 1 to 4) of bit; | ||
+ | constant table : a2D_bits := (('0', '0', '0', '1'), | ||
+ | ('1', '0', '0', '1'), ('1', '1', '0', '1') | ||
+ | ); | ||
+ | begin | ||
+ | --slice1 <= table(row, column); | ||
+ | --slice2 <= table(row, 1 TO 2); | ||
+ | --slice3 <= table(row, 1 TO 4); | ||
+ | --slice4 <= table(1 TO 3, column); | ||
+ | --slice4 <= table(1, column) & table(2, column) & tabl | ||
+ | --gen : for i in 1 to 3 generate | ||
+ | -- slice4(i) <= table(i, column); | ||
+ | --end generate; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | Responda as seguintes perguntas: | ||
+ | :1) Faça um desenho que represente o ARRAY declarado acima. | ||
+ | :2) Quantos bits são necessários para representar esse ARRAY? | ||
+ | :3) Descomente uma a uma as linhas na architecture. Verifique quais são aceitas pelo compilador? As 3 últimas formam um bloco único | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | ;Notas importantes: | ||
+ | |||
+ | A retirada de fatias (SLICES) dos ARRAYs só pode ser feita se o array foi definido com um vetor de vetores (1Dx1D ou 1Dx1Dx1D). Ainda assim é necessário respeitar a ordem dos índices do VETOR. No caso abaixo é ascendente (TO), e dentro dos limites (1 to 4). | ||
+ | |||
+ | type a1Dx1D_bit is array (1 to 3) of BIT_VECTOR(1 to 4); | ||
+ | |||
+ | * A retirada de fatias (SLICES) dos ARRAYs por coluna ou em ARRAY 2D ou 3D pode ser feita usando a retirada de elemento a elemento e concatenando-os ou atribuindo-os diretamente ao vetor de saída. | ||
+ | |||
+ | type a2D_bits is array (1 to 3, 1 to 4) of bit; | ||
+ | type a3D_bits is array (1 to 3, 1 to 4, 1 to 2) of bit; | ||
+ | |||
+ | :Concatenando por linha (ROW) ou coluna (COLUMN). | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | slice3 <= table(row, 1) & table(row, 2) & & table(row, 3) & & table(row, 4); | ||
+ | slice4 <= table(1, column) & table(2, column) & table(3, column); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :Amostrando elemento a elemento por linha (ROW) ou coluna (COLUMN | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | gen1 : for j in 1 to 4 generate | ||
+ | slice3(j) <= table(row, j); | ||
+ | end generate; | ||
+ | gen2 : for i in 1 to 3 generate | ||
+ | slice4(i) <= table(i, column); | ||
+ | end generate; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | ;Aula 16 (21 dez): | ||
+ | |||
+ | ;Como usar ARRAYs em portas?: | ||
+ | * Declaração do TYPE em PACKAGE | ||
+ | |||
+ | * Exemplo 3.8: Multiplexador com porta 1D x 1D.:: | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -----Package:------------ | ||
+ | -- File: my_pkg.vhd | ||
+ | ------------------------- | ||
+ | package my_data_types is | ||
+ | type a1Dx1D_bit_vector is array (0 to 3) of BIT_VECTOR(7 downto 0); | ||
+ | end my_data_types; | ||
+ | |||
+ | -----Main code: -------- | ||
+ | -- File: my_pkg.vhd | ||
+ | ------------------------- | ||
+ | use work.my_data_types.all; | ||
+ | |||
+ | entity mux1Dx1D is | ||
+ | port ( | ||
+ | x : in a1Dx1D_bit_vector; | ||
+ | sel : integer range 0 to 3; | ||
+ | y : out BIT_VECTOR(7 downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture pedroni of mux1Dx1D is | ||
+ | begin | ||
+ | y <= x(sel); | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Ver pag. 60 a 73 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;A declaração de RECORD: | ||
+ | |||
+ | Enquanto que em um ARRAY todos os elementos devem ser obrigatoriamente do mesmo tipo, em um RECORD (Registro) os elementos podem ser de tipos diferentes. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | type memory_access is record | ||
+ | address : integer range 0 to 255; | ||
+ | block : integer range 0 to 3; | ||
+ | data : BIT_VECTOR(15 downto 0); | ||
+ | end record; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --Escrita no RECORD | ||
+ | constant endereco : memory_access := (34, 3, "010011110101011"); | ||
+ | |||
+ | --Acesso ao RECORD | ||
+ | signal address_lido : integer range 0 to 255; | ||
+ | signal block_lido : integer range 0 to 3; | ||
+ | signal data_lido : bit_vector(15 downto 0); | ||
+ | address_lido <= endereco.address; | ||
+ | block_lido <= endereco.block; | ||
+ | data_lido <= endereco.data; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | Um exemplo de uso do RECORD é: | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity record_example is | ||
+ | port ( | ||
+ | flag : out BIT_VECTOR(1 to 4); | ||
+ | sum : out natural range 0 to 15 | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture record_example of record_example is | ||
+ | type pair is record | ||
+ | a, b : natural range 0 to 7; | ||
+ | end record; | ||
+ | type stack is array (1 to 4) of pair; | ||
+ | constant matrix : stack := ((1, 2), (3, 4), (5, 6), (7, 0)); | ||
+ | begin | ||
+ | gen : for i in 1 to 4 generate | ||
+ | flag(i) <= '1' when matrix(i).a > matrix(i).b else '0'; | ||
+ | end generate; | ||
+ | sum <= matrix(1).a + matrix(1).b; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;As declarações de SUBTYPE: | ||
+ | |||
+ | A declaração de SUBTYPE é usada para restringir as declarações de TYPE. Abaixo estão alguns exemplos. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | subtype natural is integer range 0 to integer'HIGH; | ||
+ | subtype positive is integer range 1 to integer'HIGH; | ||
+ | subtype my_integer is integer range - 32 to 31; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;Uso da declaração ALIAS: | ||
+ | A declaração ALIAS define um nome alternativo para uma entidade ou objeto. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ALIAS new_name [: specifications] IS original_name [signature]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Alguns exemplos do uso do ALIAS para objetos (SIGNAL). | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | SIGNAL data_bus: STD_LOGIC_VECTOR(31 DOWNTO 0); | ||
+ | |||
+ | --bus1 is a new name for data_bus: | ||
+ | ALIAS bus1 IS data_bus; | ||
+ | |||
+ | --bus2 is a new name for data_bus, but with a modified range: | ||
+ | ALIAS bus2: STD_LOGIC_VECTOR(32 DOWNTO 1) IS data_bus; | ||
+ | |||
+ | --bus3 is another name for data_bus, with an ascending range: | ||
+ | ALIAS bus3: STD_LOGIC_VECTOR(1 TO 32) IS data_bus; | ||
+ | |||
+ | --upper_bus1 is a new name for the upper half of data_bus | ||
+ | ALIAS upper_bus1 IS data_bus(31 DOWNTO 16); | ||
+ | |||
+ | --upper_bus2 is a new name for the upper half of data_bus, but | ||
+ | --with a modified range: | ||
+ | ALIAS upper_bus2: STD_LOGIC_VECTOR(17 TO 32) IS data_bus(31 DOWNTO 16); | ||
+ | |||
+ | --lower_bus1 is a new name for the lower half of data_bus | ||
+ | ALIAS lower_bus1 IS data_bus(15 DOWNTO 0); | ||
+ | |||
+ | --lower_bus2 is a new name for the lower half of data_bus, but | ||
+ | --with a modified range: | ||
+ | ALIAS lower_bus2: STD_LOGIC_VECTOR(1 TO 16) IS data_bus(15 DOWNTO 0); | ||
+ | </syntaxhighlight> | ||
+ | :*Ver pag. 112 a 113 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | * Veja um exemplo de uso de alias no pacote numeric_std.vhd | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | function ADD_UNSIGNED (L, R: UNSIGNED; C: STD_LOGIC) return UNSIGNED is | ||
+ | constant L_LEFT: INTEGER := L'LENGTH-1; | ||
+ | alias XL: UNSIGNED(L_LEFT downto 0) is L; | ||
+ | alias XR: UNSIGNED(L_LEFT downto 0) is R; | ||
+ | variable RESULT: UNSIGNED(L_LEFT downto 0); | ||
+ | variable CBIT: STD_LOGIC := C; | ||
+ | begin | ||
+ | for I in 0 to L_LEFT loop | ||
+ | RESULT(I) := CBIT xor XL(I) xor XR(I); | ||
+ | CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I)); | ||
+ | end loop; | ||
+ | return RESULT; | ||
+ | end ADD_UNSIGNED; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* '''NOTA''': No exemplo acima, a CONSTANT L_LEFT recebe o tamanho do parâmetro (L), que pode ser qualquer. Esse tamanho é utilizado para criar dois ALIAS para os parâmetros L e R, utilizando uma indexação (L_LEFT DOWNTO 0). Com isso é possível dentro do FOR-LOOP criar os circuitos que realizam as operações lógicas que realizam a operação de soma. | ||
+ | |||
+ | ;Sobrecarga de operadores: | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | function "+" (a : integer; b : bit) return integer is | ||
+ | begin | ||
+ | if (b = '1') then return a + 1; | ||
+ | else | ||
+ | return a; | ||
+ | end if; | ||
+ | end "+"; | ||
+ | |||
+ | function "+" (a : integer; b : std_logic) return integer is | ||
+ | begin | ||
+ | if (b = '1') then return a + 1; | ||
+ | else | ||
+ | return a; | ||
+ | end if; | ||
+ | end "+"; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | :: Ver pag. 91 a 108 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ;Como estimar os tempos de propagação?: | ||
+ | * [[Medição de tempos de propagação em circuitos combinacionais]] | ||
+ | |||
+ | ;Aula 17 (22 dez): | ||
+ | |||
+ | * A implementação de circuitos aritméticos com operadores deve seguir as seguintes recomendações: | ||
+ | :* Para o uso dos operadores o mais adequado é utilizar o padrão industrial '''STD_LOGIC_VECTOR'''. Internamente os valores das portas devem ser convertidos ou para valores '''INTEGER''' ou para '''UNSIGNED'''/'''SIGNED'''. para tal é necessário utilizar o pacote '''numeric_std''' da biblioteca '''ieee'''. | ||
+ | {{fig|3.7| Conversões entre tipos Integer, Unsigned, Signed, Std_logic_vector | Numeric_stdConvertions.gif | 600 px | [[Aritmética com vetores em VDHL]]}} | ||
+ | |||
+ | :* a conversão de um objeto (vetor)'''a_SLV''' do tipo STD_LOGIC_VECTOR para um objeto (vetor)'''a_UNS (a_SIG)''' do tipo UNSIGNED (SIGNED) é feita pela conversão de tipo '''UNSIGNED''' | ||
+ | a_UNS <= unsigned(a_SLV); | ||
+ | a_SIG <= signed(a_SLV); | ||
+ | |||
+ | :* a conversão de um objeto (vetor) '''a_UNS (a_SIG)''' do tipo UNSIGNED (SIGNED) para um objeto (escalar)'''a_INT''' do tipo INTEGER é feita pela chamada da função '''TO_INTEGER''' | ||
+ | a_INT <= to_integer(a_UNS)); | ||
+ | a_INT <= to_integer(a_SIG)); | ||
+ | |||
+ | :* a conversão de um objeto (vetor) '''a_UNS (a_SIG)''' do tipo UNSIGNED (SIGNED) para um objeto (vetor) '''a_SLV''' do tipo STD_LOGIC_VECTOR é feita pela conversão de tipo '''STD_LOGIC_VECTOR''' | ||
+ | a_SLV <= std_logic_vector(a_UNS); | ||
+ | a_SLV <= std_logic_vector(a_SIG); | ||
+ | |||
+ | :* a conversão de um objeto (escalar) '''a_INT''' do tipo para um objeto (vetor) '''a_UNS (a_SIG)''' do tipo UNSIGNED (SIGNED) é feita pela chamada da função '''TO_UNSIGNED''' ('''TO_SIGNED'''). Essa função tem um segundo parâmetro que indica o número de bits '''NBITS''' desse um objeto (vetor). | ||
+ | a_UNS <= to_unsigned(a_INT,NBITS)); | ||
+ | a_SIG <= to_signed(a_INT, NBITS)); | ||
+ | |||
+ | |||
+ | :* Também é fundamental considerar a faixa de valores coberta por <math> N </math> bits. Para tipos '''UNSIGNED''' a faixa é de <math> 0 </math> até <math> 2^{N}-1 </math>, enquanto que para '''SIGNED''' a faixa é de <math> -2^{N-1} </math> até <math> 2^{N-1}-1 </math>. | ||
+ | *Assim com 3 bits é possível representar valores entre -4 até 3 com um tipo SIGNED e 0 até 7 com um tipo UNSIGNED. | ||
+ | :* Para uso adequado dos operadores também é necessário considerar o tamanho (número de bits) requerido para o resultado em função do tamanho dos operandos. A declaração dessas funções "+", "-", "*" e "/" no PACKAGE [[Numeric std.vhd]] mostra o tamanho a ser obtido no resultado. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | function "+" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). | ||
+ | -- Result: Adds two UNSIGNED vectors that may be of different lengths. | ||
+ | |||
+ | function "-" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). | ||
+ | -- Result: Subtracts two UNSIGNED vectors that may be of different lengths. | ||
+ | |||
+ | function "*" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0). | ||
+ | -- Result: Performs the multiplication operation on two UNSIGNED vectors | ||
+ | -- that may possibly be of different lengths. | ||
+ | |||
+ | function "/" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) | ||
+ | -- Result: Divides an UNSIGNED vector, L, by another UNSIGNED vector, R. | ||
+ | -- NOTE: If second argument is zero for "/" operator, a severity level of ERROR is issued. | ||
+ | |||
+ | function "rem" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) | ||
+ | -- Result: Computes "L rem R" where L and R are UNSIGNED vectors. | ||
+ | |||
+ | function "mod" (L, R: UNSIGNED) return UNSIGNED; | ||
+ | -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) | ||
+ | -- Result: Computes "L mod R" where L and R are UNSIGNED vectors. | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | *Portanto podemos concluir que: | ||
+ | :* Para operações de "+" ou "-": O tamanho do resultado é igual ao tamanho do maior operando. | ||
+ | ::Exemplo: r[7..0] = a[7..0] + b[4..0]; a -> 8 bits; b -> 5 bits então r -> 8 bits. | ||
+ | :* Para a operações "*": O tamanho do resultado é igual a soma do tamanho dos dois operandos. | ||
+ | ::Exemplo: r[12..0] = a[7..0] * b[4..0]; a -> 8 bits; b -> 5 bits então r -> 8+5 = 13 bits. | ||
+ | :* Para "/": O tamanho do resultado é igual ao tamanho do numerador. | ||
+ | ::Exemplo: r[5..0] = a[5..0] / b[8..0]; a -> 6 bits; b -> 9 bits então r -> 6 bits. | ||
+ | * No caso da operações de "*" e "/" não ocorre ''overflow'', no entanto no caso da "+" e "-", o ''overflow/underflow'' pode ocorrer e precisa ser tratado. Isso pode ser feito acrescentando um bit adicional a saída para conter o ''overflow'' ou então sinalizar a sua ocorrência com um bit na saída do circuito. Note que no caso em que ocorrem sucessivas somas, é impraticável ficar aumentando o número de bits para evitar o ''overflow'', de modo que a sinalização do ''overflow'' ou uso de escalas, ou representação em ponto fixo ou ponto flutuante podem ser as soluções a serem adotadas. | ||
+ | * No caso das operações de "+" e "-" também pode ser necessário tratar os sinais de ''carry in'' e ''carry out'', que permitem ampliar o tamanho de um somador realizando a sua conexão em cascata, ao mesmo tempo que tratam o ''overflow''. | ||
+ | |||
+ | :* Exercício: Multiplicador/Divisor/Somador/Subtrator com sinal e sem sinal (entradas do tipo STD_LOGIC VECTOR) | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exercício: Multiplicador/Divisor/Somador/Subtrator }} | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | |||
+ | entity operadores is | ||
+ | port ( | ||
+ | a : in std_logic_vector(5 downto 0); -- 6 bits | ||
+ | b : in std_logic_vector(2 downto 0); -- 3 bits | ||
+ | sum : out std_logic_vector(? downto 0); -- ? bits | ||
+ | sub : out std_logic_vector(? downto 0); -- ? bits | ||
+ | mult : out std_logic_vector(? downto 0); -- ? bits | ||
+ | div : out std_logic_vector(? downto 0); -- ? bits | ||
+ | resto : out std_logic_vector(? downto 0) -- ? bits | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture type_conv_arch of operadores is | ||
+ | -- Declarar os sinais necessarios para fazer as conversoes de tipo | ||
+ | begin | ||
+ | -- Inserir o codigo e definir o tamanho das saidas. | ||
+ | |||
+ | |||
+ | end architecture; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;Possíveis erros de compilação: | ||
+ | |||
+ | :Error (10482): VHDL error ... : object "std_logic_vector" is used but not declared | ||
+ | ::falta declarar a biblioteca '''ieee''' e usar o pacote '''std_logic_1164''' | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | :Error (10327): VHDL error at operadores.vhd(20): can't determine definition of operator ""+"" -- found 0 possible definitions | ||
+ | ::Falta definir uma soma para SLV. '''C_slv <= A_slv + Bslv''' | ||
+ | ::Fazer a operação em INTEGER ou UN(SIGNED). | ||
+ | |||
+ | :Error (10482): VHDL error ... : object "unsigned" is used but not declared | ||
+ | ::falta usar o pacote '''numeric_std''' | ||
+ | use ieee.numeric_std.all; | ||
+ | :Error (10344): VHDL expression error at ... : expression has 6 elements, but must have 3 elements | ||
+ | ::na atribuição feita, o objeto receptor o valor tem 3 elementos ("bits"), mas o resultado da expressão tem 6 elementos ("bits"). A solução é corrigir a definição do objeto ou usar a função '''resize''' para atribuir o número correto de elementos | ||
+ | |||
+ | ;Resultados da simulação funcional. | ||
+ | Após a simulação funcional, é necessário analisar os resultados obtidos em cada operação. A figura abaixo mostra 3 analises realizadas. | ||
+ | |||
+ | {{fig|3.8| Simulação funcional do Multiplicador/Divisor/Somador/Subtrator | OperadoresQSIM.png | 600 px |}} | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | ;Recesso entre dia 24/dez/2020 e 01/02/2021: | ||
+ | Boas férias a todos. Nos encontramos no retorno. | ||
+ | |||
+ | ===Unidade 4 - Código Concorrente=== | ||
+ | * 4 AULAS | ||
+ | |||
+ | {{collapse top| Unidade 4 - Código Concorrente}} | ||
+ | |||
+ | ;Aula 18 (4 fev): | ||
+ | *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. | ||
+ | Warning (13012): Latch ... has unsafe behavior | ||
+ | |||
+ | ::* 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, ou erros de análise. | ||
+ | Error (10313): VHDL Case Statement error ...: Case Statement choices must cover all possible values of expression | ||
+ | |||
+ | ::* 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'''. | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exemplo 5.1 + 5.2}} | ||
+ | Exemplo de mux usando 3 tipos de arquiteturas: com portas discretas, com WHEN-ELSE e com WITH-SELECT | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --------------------------- | ||
+ | -- FILE mux4x1.vhd -- | ||
+ | --------------------------- | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | |||
+ | entity mux4x1 is | ||
+ | port | ||
+ | ( | ||
+ | x0, x1, x2, x3 : in STD_LOGIC; | ||
+ | sel : in STD_LOGIC_VECTOR(1 downto 0); | ||
+ | y : out STD_LOGIC | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture operators_only of mux4x1 is | ||
+ | begin | ||
+ | y <= (not sel(1) and not sel(0) and x0) or | ||
+ | (not sel(1) and sel(0) and x1) or | ||
+ | (sel(1) and not sel(0) and x2) or | ||
+ | (sel(1) and sel(0) and x3); | ||
+ | end architecture; | ||
+ | |||
+ | architecture operators_only_alias of mux4x1 is | ||
+ | alias s1 is sel(1); | ||
+ | alias s0 is sel(0); | ||
+ | begin | ||
+ | y <= (not s1 and not s0 and x0) or | ||
+ | (not s1 and s0 and x1) or | ||
+ | (s1 and not s0 and x2) or | ||
+ | (s1 and s0 and x3); | ||
+ | end architecture; | ||
+ | |||
+ | architecture with_WHEN of mux4x1 is | ||
+ | begin | ||
+ | y <= x0 when sel = "00" else | ||
+ | x1 when sel = "01" else | ||
+ | x2 when sel = "10" else | ||
+ | x3; | ||
+ | end architecture; | ||
+ | |||
+ | architecture with_SELECT of mux4x1 is | ||
+ | begin | ||
+ | with sel select | ||
+ | y <= x0 when "00", | ||
+ | x1 when "01", | ||
+ | x2 when "10", | ||
+ | x3 when others; | ||
+ | end architecture; | ||
+ | |||
+ | configuration which_mux of mux4x1 is | ||
+ | -- for operators_only end for; | ||
+ | -- for operators_only_alias end for; | ||
+ | for with_WHEN end for; | ||
+ | -- for with_SELECT end for; | ||
+ | end configuration; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Verifique os três circuitos (RTL e Technology Map) considerando as entradas x0 a x3 e a saída y com apenas um elemento. | ||
+ | *Mude a entrada '''x''' para STD_LOGIC_VECTOR(3 downto 0). Como poderia ser feito o código para que pudesse ser selecionada uma entrada entre N = 2^M. | ||
+ | *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? Veja se consegue implementar uma solução. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | :* Note que para associar uma entre várias arquiteturas para a mesma ENTITY está sendo utilizada a instrução CONFIGURATION. A ARCHITECTURE que está descomentada é a que será associada a ENTITY. Caso não se use a instrução CONFIGURATION, a última será a ARCHITECTURE utilizada. Importante todas as ARCHITECTURE devem estar sintaticamente corretas pois o configuration apenas faz a associação | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | |||
+ | configuration which_mux of mux4x1 is | ||
+ | -- for operators_only end for; | ||
+ | -- for operators_only_alias end for; | ||
+ | for with_WHEN end for; | ||
+ | -- for with_SELECT end for; | ||
+ | end configuration; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::Ver pag. 121 a 127 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | :* 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> | ||
+ | |||
+ | ;Aula 19 (8 fev): | ||
+ | *Aula suspensa por falta de luz no CPD | ||
+ | |||
+ | ;Aula 20 (9 fev): | ||
+ | * Implementação de conversor Gray para Binário. | ||
+ | :* Ver [[Código Gray]] | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ------------------------- | ||
+ | -- File: gray2bin.vhd -- | ||
+ | ------------------------- | ||
+ | entity gray2bin is | ||
+ | generic (N : natural := 4 ) | ||
+ | port | ||
+ | ( | ||
+ | g : in std_logic_vector(____) | ||
+ | b : out std_logic_vector(____) | ||
+ | ) | ||
+ | end entity | ||
+ | |||
+ | architecture ifsc_v1 of ____ is | ||
+ | begin | ||
+ | |||
+ | end architecture | ||
+ | architecture ifsc_v2 of ____ is | ||
+ | begin | ||
+ | |||
+ | end architecture | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {{collapse top| bg=lightyellow | AE3 - Implemente um circuito de incrementador Gray}} | ||
+ | *[https://moodle.ifsc.edu.br/mod/assign/view.php?id=286383 AE3 - 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(____) | ||
+ | gray_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). | ||
+ | ;BÔNUS: O primeiro aluno(a) que entregar o circuito funcionando receberá um '''bônus de 0,4 na avaliação A1'''. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | |||
+ | ;Aula 21 (11 fev): | ||
+ | |||
+ | *Exemplo 5.3 - Unidade de Lógica e Aritmética (ALU). | ||
+ | :*Escreva o código VHDL que implemente a ALU mostrada no diagrama abaixo. Use operações do tipo SIGNED. As entradas '''a''' e '''b''' e saída '''y''' ter o número de bits definido através de GENERIC, e ser do tipo STD_LOGIC_VECTOR. Faça simulação funcional para os diferentes OPCODE. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ---------------------- | ||
+ | -- File: alu.vhd -- | ||
+ | ---------------------- | ||
+ | |||
+ | entity alu is | ||
+ | generic (N : natural := 8); | ||
+ | port | ||
+ | ( | ||
+ | a, b : in std_logic(? downto 0); | ||
+ | cin : in std_logic; | ||
+ | opcode : in std_logic(? downto 0); | ||
+ | y : out std_logic(? downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture alu of alu is | ||
+ | begin | ||
+ | |||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {{fig|3.9| Unidade de Lógica e Aritmética | Alu_pedroni.png | 600 px | pag. 127 <ref name="PEDRONI2010b"/>}} | ||
+ | |||
+ | {{collapse top| bg=lightyellow | AE4 - ALU modificada }} | ||
+ | *[https://moodle.ifsc.edu.br/mod/assign/view.php?id=286382 AE4 - ALU modificada] | ||
+ | 1) Faça um novo circuito que inclua um sinal que indica "erro" quando ocorrer overflow/underflow nas operações de soma, incremento ou decremento. | ||
+ | |||
+ | 2) Faça um novo circuito que sature o sinal de saída no máximo positivo ou negativo nas situações de erro. | ||
+ | |||
+ | Para ambos circuitos modificados: | ||
+ | *Faça simulações funcionais com Modelsim (ou QSIM) utilizando 3 bits, mostrando tanto o funcionamento normal como as situações de erro. É necessário fazer os testes para os diferentes OPCODES. No caso do OPCODES lógicos um ou dois testes são suficientes, mas no caso do incremento, decremento, é recomendado que envolva os limites "000" e "111" nas entradas. | ||
+ | *Deve ser feita a mesma simulação para o circuito original e as duas versões modificadas. | ||
+ | *Escreva o código VHDL e analise o número de elementos lógicos necessários. | ||
+ | |||
+ | ;Bonus: | ||
+ | *(0.3 pontos na avaliação A1) para o primeiro aluno que entregar o código com a indicação de erro | ||
+ | *(0.3 pontos na avaliação A1) para o primeiro aluno que entregar o código com a saturação da saída. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | :*Ver pag. 127 a 134 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | <!-- | ||
+ | {{collapse top| bg=lightyellow | Exemplo 3.6: }} | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | --> | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 5 - Código Sequencial=== | ||
+ | * 7 AULAS | ||
+ | {{collapse top| expand=true| Unidade 5 - Código Sequencial}} | ||
+ | |||
+ | ;Aula 22 (18 fev): | ||
+ | *Marcada a avaliação A1 (até Código Concorrente) para 4 mar; Estudar https://moodle.ifsc.edu.br/mod/wiki/view.php?id=286372 | ||
+ | *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). | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --Flip Flop tipo D com reset assincrono, sensivel a borda de subida. | ||
+ | process (clock,reset) | ||
+ | begin | ||
+ | if (reset = '1') then | ||
+ | q <= '0'; | ||
+ | -- elsif (clock'event and clock = '1') then or | ||
+ | elsif (rising_edge(clock)) then | ||
+ | q <= d; | ||
+ | end if; | ||
+ | end process; | ||
+ | |||
+ | --Flip Flop tipo D com preset assincrono e sinal de enable, sensivel a borda de descida. | ||
+ | process (clock, preset) | ||
+ | begin | ||
+ | if (preset = '1') then | ||
+ | q <= '1'; | ||
+ | elsif (falling_edge(clock)) then | ||
+ | if (enable = '1') then | ||
+ | q <= d; | ||
+ | end if; | ||
+ | end if; | ||
+ | end process; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::* Comparar com Latch (sem clk'event). | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | --Latch tipo D com reset assincrono. | ||
+ | process (enable, reset, d) | ||
+ | begin | ||
+ | if (reset = '1') then | ||
+ | d <= '0'; | ||
+ | elsif (enable='1')) then | ||
+ | q <= d; | ||
+ | end if; | ||
+ | end process; | ||
+ | </syntaxhighlight> | ||
+ | :*Ver pag. 151 a 156 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | |||
+ | ;Aula 23 e 24 (22 e 23 fev): | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- Flip Flop tipo D com reset síncrono sensível a borda de subida. | ||
+ | -- Modifique a descrição para que o reset_ass seja assíncrono e reset_sinc seja síncrono. | ||
+ | -- Note que a função rising_edge(clock) é equivalente a (clock'event and clock'last_value = '0' and clock = '1')) | ||
+ | |||
+ | process (clock, reset) | ||
+ | begin | ||
+ | if (reset = '1') then | ||
+ | q <= '0'; | ||
+ | elsif (clock'event and clock'last_value = '0' and clock = '1')) then | ||
+ | q <= d; | ||
+ | end if; | ||
+ | end process; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | * Simulação funcional do DFFs e do Latch | ||
+ | |||
+ | * Porta paralela com N DFFs. | ||
+ | |||
+ | * Contador crescente 0-N (baseado no Ex.6.2), com N = 2^Mbits-1 (1 3 7 15) | ||
+ | :* Com overflow no valor máximo | ||
+ | |||
+ | * Contador crescente 0-N (baseado no Ex.6.2), com N =/= 2^Mbits (5, 10) | ||
+ | :* Com parada no valor máximo | ||
+ | :* Com overflow no valor máximo | ||
+ | |||
+ | * Contador decrescente 0-N (baseado no Ex.6.2), com N =/= 2^Mbits (5, 10) | ||
+ | :* Com parada no valor mínimo | ||
+ | :* Com underflow no valor máximo | ||
+ | |||
+ | ;Aula 25 (25 fev): | ||
+ | |||
+ | * Projetar um contador em BCD entre 0 e 99, com entrada de clock, reset e saidas unidade(0 a 9) e dezena (0 a 9). | ||
+ | :* versão 1 - contagem crescente. | ||
+ | :* versão 2 - contagem decrescente. | ||
+ | :* versão 3 - contagem crescente ou decrescente controlado por uma entrada DIR. Se DIR = '0' a contagem é crescente se DIR = '1' a contagem é decrescente. | ||
+ | :'''Nota:''' | ||
+ | ::Antes de implementar a versão 3 verifique no RTL das versões 1 e 2 as diferenças, e pense nas possibilidades de reutilização do hardware. O que é comum entre elas e o que precisa ser acrescentado na versão 3. | ||
+ | ::Tente obter uma versão com o mínimo acréscimo em elementos lógicos. | ||
+ | |||
+ | ;Aula 26 (1 mar): | ||
+ | * Aula suspensa devido a problemas de conexão (Excesso de chuva nos municípios da grande Floripa). | ||
+ | * https://g1.globo.com/sc/santa-catarina/noticia/2021/03/01/chuva-em-sc-provoca-alagamentos-desmoronamentos-e-suspende-aulas.ghtml | ||
+ | * A avaliação A1 do dia 4 mar foi adiada para 11 mar. | ||
+ | |||
+ | ;Aula 27 a 29 (4, 8 e 9 mar): | ||
+ | * Dúvidas da prova. Ver [https://moodle.ifsc.edu.br/mod/wiki/view.php?id=286372 lista de exercícios dos capítulos 2 a 5] | ||
+ | |||
+ | ;Aula 30 (11 mar): | ||
+ | * Avaliação A1. A avaliação iniciará as 9h20 na [http://meet.google.com/hto-grwk-pzt sala remota]. | ||
+ | |||
+ | |||
+ | ;Aula 31 (15 mar): | ||
+ | * Registrador de deslocamento (Ex.6.3) | ||
+ | {{fig|4.1| RTL do registrador de deslocamento (Ex.6.3) | ShifRegRight.png | 800 px |}} | ||
+ | |||
+ | :Versão 1 - Implementação com 4 FF D. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity shift_reg4_right is | ||
+ | port | ||
+ | ( | ||
+ | din, clk, rst : in std_logic; | ||
+ | dout : out std_logic | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ifsc of shift_reg4_right is | ||
+ | begin | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :Versão 2 - Implementação com for generate da conexão de FF D. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity shift_reg_right is | ||
+ | generic (N : integer := 4); | ||
+ | port | ||
+ | ( | ||
+ | din, clk, rst : in std_logic; | ||
+ | dout : out std_logic | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ifsc of shift_reg_right is | ||
+ | begin | ||
+ | |||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | :Versão 3 - Implementação com formação de agregado via concatenação. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity shift_reg_right is | ||
+ | generic (N : integer := 4); | ||
+ | port | ||
+ | ( | ||
+ | din, clk, rst : in std_logic; | ||
+ | dout : out std_logic | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ifsc of shift_reg_right is | ||
+ | begin | ||
+ | process (clk, rst) | ||
+ | variable q : std_logic_vector (N-1 downto 0); | ||
+ | begin | ||
+ | if (rst = '1') then | ||
+ | q := (others => '0'); | ||
+ | elsif (clk'EVENT and clk = '1') then | ||
+ | q := din & q (N-1 downto 1); | ||
+ | end if; | ||
+ | dout <= q(0); | ||
+ | end process; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Simule o Registrador de Deslocamento usando o QSIM, visualizando os sinais internos para perceber o deslocamento. | ||
+ | *Repita a simulação usando o Modelsim. | ||
+ | |||
+ | ;Aula 32 (18 mar): | ||
+ | |||
+ | Aproveitando a versão 3 ou 2 do Shift Register da aula anterior, projete e faça a simulação dos dois circuitos indicados a seguir: | ||
+ | |||
+ | * Embrião de um conversor serial para paralelo. | ||
+ | |||
+ | {{fig|4.2| RTL do embrião de um conversor serial para paralelo | Serial2Parallel.png | 800 px |}} | ||
+ | |||
+ | :Para usar o hardware do ShifRegister como base para um conversor serial para paralelo, basta conectar as saídas dos FFD em portas '''DataOut'''(N-1) até '''DataOut'''(0). Assim, os sinais seriais da entrada '''SerialIn''' estarão disponíveis nestas saídas '''DataOut''' a cada N clocks. | ||
+ | |||
+ | {{fig|4.3| Simulação funcional do embrião de um conversor serial para paralelo | Serial2Parallel_SIM.png | 800 px |}} | ||
+ | |||
+ | :Uma simulação com o QSIM é mostrada na figura acima. | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity serial2parallel is | ||
+ | port | ||
+ | ( | ||
+ | clk, rst : in std_logic; | ||
+ | SerialIn : in std_logic; | ||
+ | DataOut : out std_logic_vector(N-1 downto) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ifsc of serial2parallel is | ||
+ | begin | ||
+ | |||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Embrião de um conversor paralelo para serial. | ||
+ | |||
+ | {{fig|4.4| Simulação funcional do embrião de um conversor paralelo para serial | Paralelo2Serial.png | 800 px |}} | ||
+ | |||
+ | :Para usar o hardware do ShiftRegister como base para um conversor paralelo para serial, é necessário carregar os dados paralelos do '''DataIn''' com o sinal '''Load''' nos FFD e em seguida fazer o deslocamento deles bit por bit durante N clocks. Na saída '''SerialOut''' do ShiftRegister os dados serão seriazados, aparecendo um cada clock. | ||
+ | |||
+ | {{fig|4.5| Simulação funcional do embrião de um conversor paralelo para serial | Paralelo2Serial_SIM.png | 800 px |}} | ||
+ | |||
+ | :Uma simulação com o QSIM é mostrada na figura acima. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity parallel2serial is | ||
+ | port | ||
+ | ( clk, rst : in std_logic; | ||
+ | Load : in std_logic; | ||
+ | DataIn : in std_logic_vector(N-1 downto); | ||
+ | SerialOut : out std_logic | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ifsc of parallel2serial is | ||
+ | begin | ||
+ | |||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;Aula 33 (22 mar): | ||
+ | *Aprendizado prático de simulação com Modelsim | ||
+ | |||
+ | ;Aula 34 (23 mar): | ||
+ | |||
+ | Instruções do tipo '''LOOP''': LOOP incondicional, FOR-LOOP, WHILE-LOOP, NEXT, EXIT | ||
+ | |||
+ | *Instrução '''LOOP''' incondicional: | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] LOOP | ||
+ | afirmação_sequencial; | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | END LOOP [rótulo]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Instrução '''FOR-LOOP''': | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] FOR identificador IN faixa LOOP | ||
+ | afirmação_sequencial; | ||
+ | afirmação_sequencial; | ||
+ | ... | ||
+ | END LOOP [rótulo]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Instrução '''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> | ||
+ | |||
+ | *Instrução 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> | ||
+ | |||
+ | *Instrução 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> | ||
+ | |||
+ | *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> | ||
+ | |||
+ | * Exemplos: | ||
+ | :* Leading Zeros (LOOP com EXIT) (Ex 6.5) - Esse circuito deve determinar quantos zeros tem em um vetor de entrada '''Vin''' antes do primeiro bit '1', começando da esquerda para a direita. | ||
+ | ::*Fazer a síntese do circuito; fazer simulação no Modelsim; analisar a forma como o compilador implementou o incrementador. | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity leading_zeros is | ||
+ | generic (N : natural := 8); | ||
+ | port | ||
+ | ( Vin : in std_logic_vector(0 to N-1); | ||
+ | count : out integer range 0 to N | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ____ of leading_zeros is | ||
+ | |||
+ | begin | ||
+ | process (data) | ||
+ | variable count : integer ____ 0 to N | ||
+ | begin | ||
+ | count := 0; | ||
+ | for i ___ data'range ____ | ||
+ | case data(i) is | ||
+ | when '0' => count := count + 1; | ||
+ | when _____ => exit; | ||
+ | end ___ | ||
+ | end ____ | ||
+ | zeros <= count; | ||
+ | end process; | ||
+ | end _______; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :* Contador de zeros (FOR LOOP) - Esse circuito deve determinar quantos zeros tem em um vetor de entrada '''Vin'''. | ||
+ | ::*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"/> | ||
+ | |||
+ | * Carry-Ripple Adder (FOR-LOOP) (Ex 6.4) - apenas analisar. | ||
+ | :* Um somador do tipo carry ripple utiliza o bloco básico '''full adder''' para construir somadores de qualquer número de bits. Os bits carry são adicionados aos blocos posteriores, produzindo um hardware combinário. | ||
+ | :* O full adder é baseado nas funções. | ||
+ | ::<math> s_k = a_k \oplus b_k \oplus c_k </math> | ||
+ | ::<math> c_{k+1} = a_k . b_k + a_k . c_k + b_k . c_k </math> | ||
+ | :: onde <math> c_{k+1} </math> é o '''carry out''', <math> c_{k} </math> é o '''carry in''' | ||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity carry_ripple_adder is | ||
+ | generic (N : integer := 4); | ||
+ | port ( | ||
+ | a, b : std_logic_vector (N-1 downto 0); | ||
+ | cin : std_logic | ||
+ | s : out std_logic_vector (N downto 0); | ||
+ | cout : out std_logic; | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture estrutural of carry_ripple_adder | ||
+ | begin | ||
+ | -- Uso de um codigo sequencial para geracao de um circuito combinacional | ||
+ | process (a, b, cin) | ||
+ | variable c : std_logic_vector(N downto); | ||
+ | begin | ||
+ | c(0) := cin; | ||
+ | for i in 0 to N - 1 loop | ||
+ | -- Codigo de um full adder | ||
+ | -- soma de dois bits e carry_in do full adder anterior | ||
+ | s(i) <= a(i) xor b(i) xor c(i); | ||
+ | -- geraao do carry_out para o proximo full adder | ||
+ | c(i + 1) := (a(i) and b(i)) or (a(i) and c(i)) or (b(i) and c(i)); | ||
+ | end loop; | ||
+ | cout <= c(N); | ||
+ | end process; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Instrução '''WAIT''': WAIT UNTIL, WAIT FOR (simulação apenas), WAIT ON (não implementada no Quartus II). | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | [rótulo:] WAIT UNTIL <condition>; | ||
+ | [rótulo:] WAIT ON sensitivity_list; | ||
+ | [rótulo:] WAIT FOR time_expression; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | :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'''. | ||
+ | |||
+ | ;Aula 35 (25 mar): | ||
+ | * Exemplo: 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). | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | entity timer0_9 is | ||
+ | port ( | ||
+ | clk1seg,rst: in std_logic; | ||
+ | count_out : out std_logic_vector(3 downto 0); | ||
+ | ssd_out : out std_logic_vector(6 downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture ifsc_v1 of timer0_9 is | ||
+ | |||
+ | begin | ||
+ | process (rst, clk1seg) | ||
+ | -- processo do contador de 0 a 9 | ||
+ | end process; | ||
+ | |||
+ | process (count) | ||
+ | begin | ||
+ | -- processo do codificador de binario para display de sete segmentos | ||
+ | end process; | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A simulação funcional do circuito deverá produzir uma saída semelhante a mostrada abaixo: | ||
+ | {{fig|4.6| simulação funcional do timer0_9 | Timer0_9_SIM_FUNC.png | 600 px | }} | ||
+ | |||
+ | A simulação com timing do circuito deverá produzir uma saída semelhante a mostrada abaixo: | ||
+ | {{fig|4.7| simulação com timing do timer0_9 | Timer0_9_SIM_TIME.png | 600 px | }} | ||
+ | |||
+ | Depois acrescentar a esse circuito um módulo que permita a partir de um sinal de clock com frequência de fclk = 50MHz (T = 20 ns), obter um clock de f = 1 Hz (T = 1 s) | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | process (rst, clk50MHz) | ||
+ | -- processo do divisor de clock de 50MHz para 1 Hz | ||
+ | end process; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | 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 para configurar o dispositivo e seus pinos 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 | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | ssd_out <= not ssd; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Se quiser usar algum led na matriz de led do kit Mercúrio é necessário colocar '0' da coluna do Led e '1' na linha correspondente, ou seja utilizar um segundo pino para acender o led. | ||
+ | |||
+ | 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 Pedroni VHDL 2ed Tutorial of ModelSim 10.1d] | ||
+ | * [[Media:modelsim_tut.pdf |ModelSim® Tutorial]] -v10.0d | ||
+ | * [[Documentação do ModelSim]], para conhecer mais a fundo o MODELSIM. | ||
+ | |||
+ | ;Aula 36 (29 mar): | ||
+ | ====AE5 ==== | ||
+ | {{collapse top| bg=lightyellow | AE5 - Laboratório de programação de FPGA - Timer 00 a 99 segundos sem o uso de componente - versão 1}} | ||
+ | |||
+ | *[https://moodle.ifsc.edu.br/mod/assign/view.php?id=357699 AE5 - Laboratório de programação de FPGA - Timer 00 a 99 segundos em componente versão 1] | ||
+ | Projete um contador BCD de 00 a 99 configurável com saída em 2 mostradores de 7 segmentos. | ||
+ | *Utilize o timer 0 a 9 desenvolvido em aula como base, substituindo o contador 0 a 9 pelo contador BCD 00 a 99. | ||
+ | *O contador deve ser configurável para contar qualquer valor entre 01 até 99. | ||
+ | *Efetue a simulação funcional (Usando Modelsim) fazendo a contagem de 00 a 11 e também de 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. | ||
+ | * 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 para configurar o dispositivo e seus pinos estão em [[Preparando para gravar o circuito lógico no FPGA]]. | ||
+ | * 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. | ||
+ | |||
+ | ;Bonus: | ||
+ | *(1 pontos na avaliação A2) para o primeiro estudante que entregar o QAR com o código e as simulações feitas | ||
+ | *(0.5 pontos na avaliação A2) para o primeiro estudante que entregar o arquivo SOF fazendo a contagem corretamente no kit da Macnica Mercúrio IV. | ||
+ | *(1 ponto na avaliação A2) para o primeiro estudante que entregar o arquivo SOF que além de fazer a contagem, mostre a matriz de leds indicando o valor BCD da dezena na primeira linha e o valor BCD da unidade na segunda linha. Dicas de como fazer ver [[Como utilizar a matriz de leds do kit Mercurio IV da Macnica]] | ||
+ | <center> {{#ev:youtube|orjy0GURH_U}} </center> | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | ===Unidade 6 - Projeto a nível de Sistema=== | ||
+ | * 4 AULAS | ||
+ | {{collapse top| expand=true | Unidade 6 - Projeto a nível de Sistema}} | ||
+ | |||
+ | ; Aula 37 (1 abr): | ||
+ | *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: Porta NAND de 3 entradas. | ||
+ | |||
+ | * Criação de '''COMPONENT''' redimensionáveis. GENERIC -> '''GENERIC MAP''' | ||
+ | :* Exemplo: Registrador de deslocamento. | ||
+ | |||
+ | *Ver outros exemplos | ||
+ | :*Exemplo: Registrador Circular Ex. 8.2 | ||
+ | :*Exemplo: Porta E com N entradas. | ||
+ | :*Exemplo: Detector de Paridade Ex. 8.3 | ||
+ | :* Ver pag. 201 a 213 de <ref name="PEDRONI2010b"/> | ||
+ | |||
+ | ; Aula 38 (5 abr): | ||
+ | :* 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). | ||
+ | |||
+ | |||
+ | ====AE6 ==== | ||
+ | {{collapse top| bg=lightyellow | AE6 - Laboratório de programação de FPGA - Timer 00 a 99 segundos com componente - versão 2}} | ||
+ | |||
+ | <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, com 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. | ||
+ | |||
+ | {{fig|5.1| RTL do timer 00 a 99 segundos | rtl_timer99sec.png | 600 px | }} | ||
+ | |||
+ | * 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. | ||
+ | |||
+ | {{fig|5.2| Simulação do timer 00 a 99 segundos | sim_timer99sec.png | 800 px | }} | ||
+ | |||
+ | 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}} | ||
+ | <pre> | ||
+ | </pre> | ||
+ | {{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}} | ||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | {{collapse bottom}} | ||
+ | :* Analise 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. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ; Aula 39 (6 abr): | ||
+ | |||
+ | 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 síntese 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'''. | ||
+ | |||
+ | 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> | ||
+ | |||
+ | :*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> | ||
+ | |||
+ | ;Exemplos de uso ASSERT, FUNCTION e PROCEDURE: | ||
+ | |||
+ | * Exemplo: Declaração de FUNCTION em ARCHITECTURE Ex.9.1 | ||
+ | :*Aplicação no projeto do '''timer0_9''' | ||
+ | |||
+ | * Exemplo: Declaração em FUNCTION PACKAGE Ex. 9.2 | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- FILE: comparator.vhd | ||
+ | -- Fonte: PEDRONI, Volnei A. Circuit Design and Simulation with VHDL; 2 ed. Massachusetts-EUA:MIT, 2010. | ||
+ | |||
+ | library ieee; | ||
+ | use ieee.numeric_std.all; | ||
+ | use work.my_package.all; | ||
+ | entity organizer is | ||
+ | generic (size : natural := 3); | ||
+ | port | ||
+ | ( | ||
+ | x : in UNSIGNED(2 to 5); | ||
+ | y : out UNSIGNED(size - 1 downto 0) | ||
+ | ); | ||
+ | end entity; | ||
+ | architecture organizer of organizer is | ||
+ | begin | ||
+ | y <= order_and_fill(x, size); | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- FILE: my_pkg.vhd | ||
+ | -- Fonte: PEDRONI, Volnei A. Circuit Design and Simulation with VHDL; 2 ed. Massachusetts-EUA:MIT, 2010. 608 p. ISBN 9780262014335 | ||
+ | |||
+ | library ieee; | ||
+ | use ieee.numeric_std.all; | ||
+ | package my_package is | ||
+ | function order_and_fill (input : UNSIGNED; bits : natural) return UNSIGNED; | ||
+ | end package; | ||
+ | |||
+ | package body my_package is | ||
+ | function order_and_fill (input : UNSIGNED; bits : natural) return UNSIGNED is | ||
+ | variable a : UNSIGNED(input'LENGTH - 1 downto 0); | ||
+ | variable result : UNSIGNED(bits - 1 downto 0); | ||
+ | begin | ||
+ | assert (input'LENGTH <= bits) | ||
+ | report "Improper input size!" | ||
+ | severity FAILURE; | ||
+ | if (input'LEFT > input'RIGHT) then | ||
+ | a := input; | ||
+ | else | ||
+ | for i in a'range loop | ||
+ | a(i) := input(input'LEFT + i); | ||
+ | end loop; | ||
+ | end if; | ||
+ | if (a'LENGTH < bits) then | ||
+ | result(bits - 1 downto a'LENGTH) := (others => '0'); | ||
+ | result(a'LENGTH - 1 downto 0) := a; | ||
+ | else | ||
+ | result := a; | ||
+ | end if; | ||
+ | return result; | ||
+ | end function; | ||
+ | end package body; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Exemplo: min_max Ex.9.4 | ||
+ | {{fig|6.1|Fluxograma da PROCEDURE min_max| fluxogramMinMax.png| 600 px | pag. 232 de <ref name="PEDRONI2010b"/> }} | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- FILE: comparator.vhd | ||
+ | -- Fonte: PEDRONI, Volnei A. Circuit Design and Simulation with VHDL; 2 ed. Massachusetts-EUA:MIT, 2010. | ||
+ | |||
+ | use work.my_package.all; | ||
+ | |||
+ | entity comparator is | ||
+ | port | ||
+ | ( | ||
+ | a, b, c : in integer range 0 to 255; | ||
+ | min, max : out integer range 0 to 255 | ||
+ | ); | ||
+ | end entity; | ||
+ | |||
+ | architecture comparator of comparator is | ||
+ | begin | ||
+ | min_max(a, b, c, min, max); | ||
+ | end architecture; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang=vhdl> | ||
+ | -- FILE: my_pkg.vhd | ||
+ | -- Fonte: PEDRONI, Volnei A. Circuit Design and Simulation with VHDL; 2 ed. Massachusetts-EUA:MIT, 2010. | ||
+ | |||
+ | |||
+ | package my_package is | ||
+ | procedure min_max ( | ||
+ | signal a, b, c : in integer; | ||
+ | signal min, max : out integer | ||
+ | ); | ||
+ | end package; | ||
+ | package body my_package is | ||
+ | procedure min_max ( | ||
+ | signal a, b, c : in integer range 0 to 255; | ||
+ | signal min, max : out integer range 0 to 255) is | ||
+ | begin | ||
+ | if (a >= b) then | ||
+ | if (a >= c) then | ||
+ | max <= a; | ||
+ | if (b >= c) then | ||
+ | min <= c; | ||
+ | else | ||
+ | min <= b; | ||
+ | end if; | ||
+ | else | ||
+ | max <= c; | ||
+ | min <= b; | ||
+ | end if; | ||
+ | else | ||
+ | if (b >= c) then | ||
+ | max <= b; | ||
+ | if (a >= c) then | ||
+ | min <= c; | ||
+ | else min <= a; | ||
+ | end if; | ||
+ | else | ||
+ | max <= c; | ||
+ | min <= a; | ||
+ | end if; | ||
+ | end if; | ||
+ | end procedure; | ||
+ | end package body; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | ::* Exercícios: 9.1 a 9.4, 9.6 a 9.9 | ||
+ | :* Ver pag. 213 a 239 de <ref name="PEDRONI2010b"/>) | ||
+ | |||
+ | <!-- | ||
+ | ;Aula XX e XX (24 e 26 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 parallel_reg is | ||
+ | entradas clk_in, rst, ena, d_in[N-1..0] | ||
+ | saídas d_out[N-1..0] | ||
+ | |||
+ | : Outros componentes necessários. | ||
+ | |||
+ | * Simular o serializador e deserializador com ModelSim. | ||
+ | * Implementar em um kit FPGA (Mercurio IV) usando o '''lab home office'''. | ||
+ | |||
+ | ;Aula XX XX (1 e 3 jul): | ||
+ | * Atividade extraclasse, ficou dividida em: | ||
+ | :*Equipe 1: Detalhar a '''architecture''' do componente '''div_clk''' e fazer sua simulação. | ||
+ | ::-Verificar se o '''clk_out''' está alto durante apenas um período do '''clk_in'''. Esse período deve ser entre duas bordas de descida do '''clk_in'''. | ||
+ | :*Equipe 1: Detalhar a '''architecture''' do componente '''parallel_reg''' e fazer sua simulação. | ||
+ | :*Equipe 2: Detalhar a '''architecture''' do componente '''shift_reg''', e fazer a simulação. | ||
+ | ::-Verificar a transferência dos dados da entrada serial para a saída paralela (função Desserializador). | ||
+ | ::-Verificar a transferência dos dados da entrada paralela para a saída serial (função Serializador). | ||
+ | ::-Verificar a transferência dos dados da entrada serial para a saída serial (função Delay). | ||
+ | ::-Verificar a transferência dos dados da entrada paralela para a saída paralela (função porta Paralela). | ||
+ | ::-Verificar a possibilidade de utilizar esse componente no lugar do '''parallel_reg'''. | ||
+ | * As equipes devem terminar de simular os componentes e integrá-los no projeto. | ||
+ | * Após a integração deverá ser feita a simulação do sistema completo. | ||
+ | * Mapear os pinos do FPGA para fazer o teste de funcionamento com um baud-rate de 1bit/s, entrada chaves, saídas leds. | ||
+ | --> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ===Unidade 7 - Maquinas de Estado Finitas=== | ||
+ | {{collapse top| expand=true | Unidade 7 - Maquinas de Estado Finitas}} | ||
+ | * 3 AULAS | ||
+ | |||
+ | ; Aula 40 (8 abr): | ||
+ | *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"; | ||
+ | -- ATTRIBUTE SYN_ENCODING OF state : TYPE IS "safe"; | ||
+ | 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. | ||
+ | {{fig|7.1|Exemplo de diagrama de estados de uma FSM Fig11.1(a) e implementação em hardware da FSM Fig11.2(a)|Fig11_1_FSM.png|800 px|Figura 11.1 e 11.2 de <ref name="PEDRONI2010b"/>}} | ||
+ | :* 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 280 de <ref name="PEDRONI2010b"/> | ||
+ | :: Ver [https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/qts/archives/quartusii_handbook_archive_131.pdf Quartus II Handbook Version 13.1: Manually Specifying Enumerated Types Using the enum_encoding Attribute, pag 16-37] sobre a atribuição manual do enum_encoding. | ||
+ | :: Note que o uso desse atributo faz com que o compilar do Quartus não reconheça a FSM, mas use logica regular para representar o sistema. | ||
+ | :: Ver [https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/qts/archives/quartusii_handbook_archive_131.pdf Quartus II Handbook Version 13.1: Safe State Machines, pag 16-38]. | ||
+ | |||
+ | *Introdução ao Projeto de Maquinas de Estado Finitas (FSM) em VHDL | ||
+ | :* Máquina de vender doces | ||
+ | ::*Use o template da FSM para modelar o sistema mostrado na figurar a seguir. | ||
+ | |||
+ | {{fig|7.2|FSM - Máquina de vender doces (diagrama de estados)|FSM_MVD.png|800 px|Adaptado da Figura 11.3 de <ref name="PEDRONI2010b"/> }} | ||
+ | |||
+ | {{fig|7.3|FSM - Máquina de vender doces (diagrama de estados com default |FSM_MVD_default.png|800 px|}} | ||
+ | |||
+ | ::*Simule a FSM com Modelsim utilizando um testbench em VHDL para gerar o teste mostrado na figura abaixo. | ||
+ | {{fig|7.4|FSM - Máquina de vender doces (simulação)|FSM_tb40.png|800 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"/> | ||
+ | :: '''Dica''': para desenhar a FSM recomendo utilizar um software on-line para tal finalidade. Por Ex. [https://online.visual-paradigm.com/pt/ Visual Paradigm]. | ||
+ | |||
+ | ; Aula 41 (12 abr): | ||
+ | *Introdução ao Projeto de Maquinas de Estado Finitas (FSM) em VHDL | ||
+ | :* O problema de oscilando entre os estados em FSM. | ||
+ | |||
+ | {{fig|7.5| FSM - alarme (oscilando entre os estados quando remoto é 1) |alarme_erro.png|500 px|Adaptado de Figura 11.9(a) de <ref name="PEDRONI2010b"/>}} | ||
+ | |||
+ | ::* Solução através do uso de FLAG | ||
+ | |||
+ | {{fig|7.6| FSM - alarme (solução com flag) |alarme_flag.png|500 px|Adaptado de Figura 11.9(b) de <ref name="PEDRONI2010b"/>}} | ||
+ | |||
+ | ::* Solução através do uso de estados de WAIT adicionais. | ||
+ | |||
+ | {{fig|7.7| FSM - alarme (solução com estados de WAIT) |alarme_wait.png|500 px|Adaptado de Figura 11.9(c) de <ref name="PEDRONI2010b"/>}} | ||
+ | |||
+ | {{fig|7.8| Simulação da FSM - alarme (solução com estados de WAIT) |simulation_alarme_wait.png|800 px|}} | ||
+ | |||
+ | :: Ver pag. 292 a 297 de <ref name="PEDRONI2010b"/> | ||
+ | *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 | ||
+ | |||
+ | ====ATUAL==== | ||
+ | ;Aula 42 (15 abr): | ||
+ | |||
+ | * Projeto de FSM temporizadas (nas quais as transições são ativadas também pelo tempo). | ||
+ | {{fig|7.9| Tipos de FSM (Condicional, Temporizada e Hibrida) |FSM_type.png|800 px|Figura 11.12 de <ref name="PEDRONI2010b"/>}} | ||
+ | |||
+ | * 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"/> | ||
+ | ;Exemplo de FSM temporizada - semáforo temporizado: | ||
+ | * Usando o template acima descreva em VHDL a FSM de um controlador de semáforo Regular indicado pela FSM da figura abaixo: | ||
+ | {{fig|7.10| Diagrama de estados do controlador de semáforo |Semaforo_FSM_v2.png|800 px|}} | ||
+ | |||
+ | {{fig|7.11| Simulação do controlador de semáforo no Modelsim |Semaforo_FSM_v2_ModelSim.png|800 px|}} | ||
+ | |||
+ | {{collapse top| bg=lightyellow | Exercício - Semaforo}} | ||
+ | * 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"/>). | ||
+ | {{fig|7.12| Diagrama de estados do controlador de semáforo |Semaforo_FSM_VD.png|800 px| Adaptado de Figura 11.15 de <ref name="PEDRONI2010b"/>}} | ||
+ | |||
+ | {{fig|7.13| Diagrama de estados do Quartus do controlador de semáforo |Semaforo_FSM.png|800 px|}} | ||
+ | |||
+ | * Para definir as temporizações utilize GENERICs que permitam instanciar diferentes semáforos em um projeto de controle de tráfego de uma avenida. | ||
+ | : Para uma instância do semáforo S1 use (timeRY = 2 segundos; timeGR = 40 segundos; timeYR = 2 segundos; timeRG = 15 segundos. | ||
+ | : Para uma instância do semáforo S2 use (timeRY = 5 segundos; timeGR = 90 segundos; timeYR = 5 segundos; timeRG = 30 segundos. | ||
+ | * Considere que o sinal de clock tem período de 1 segundo. | ||
+ | * Realize a simulação dos semáforos S1 e S2, destacando as saídas com as cores correspondentes, conforme mostrado abaixo: | ||
+ | {{fig|7.14| Simulação do controlador de semáforo no Modelsim |Semaforo_ModelSim.png|800 px|}} | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | ==Avaliações== | ||
+ | Nas avaliações A1 e A2 são com consulta apenas as folhas de consulta entregues: | ||
+ | <!-- | ||
+ | *[[Media:VHDL_QRC-Qualis.pdf | VHDL QUICK REFERENCE CARD]] - Qualis | ||
+ | *[[Media:VHDL1164_QRC-Qualis.pdf | VHDL 1164 PACKAGES QUICK REFERENCE CARD]] Qualis | ||
+ | --> | ||
+ | *[[Media:VHDL_QRC-SynthWorks.pdf | VHDL Quick Reference]] - SynthWorks | ||
+ | *[[Media:VHDL_Type_Operators_QR-SynthWorks.pdf | VHDL Types and Operators Quick Reference]] - SynthWorks | ||
+ | *[[Media:ModelSim_QR-SynthWorks.pdf |ModelSim Quick Reference]] - SynthWorks | ||
+ | *[[Media:Tabelas_Pedroni.pdf | Tabelas das figuras 3.6, 3.10 e 4.1]] do livro do Pedroni. | ||
+ | *[[Arquivo:Numeric_std_conversions.png | Diagrama de conversões de tipos numéricos no pacote Numeric_std ]] | ||
+ | ::Dica use também como fonte de consulta os '''templates''' do Quartus. | ||
+ | ::Ao final das avaliações o aluno deverá enviar a avaliação para a plataforma Moodle com os arquivos solicitados. | ||
+ | |||
+ | ===Projeto Final (PF)=== | ||
+ | * O projeto final é uma atividade de avaliação que será desenvolvida de forma individual. Consiste no desenvolvimento de um sistema que aplica os conhecimento adquiridos durante o semestre. A avaliação do projeto final corresponde a 36% do peso no conceito final. São avaliados no projeto final os quesitos: | ||
+ | :1) Sistema desenvolvido (projeto, simulação e realização, demonstração do hardware); (18%) | ||
+ | :2) Relatório com a documentação completa do projeto; (18%) | ||
+ | |||
+ | {{collapse top | expand = true | APF - Projeto Final - Sistema de controle de veículos em uma Avenida(Entrega e prazos ver Moodle)}} | ||
+ | * O projeto deverá desenvolver um sistema de controle de veículos para o sistema viário indicado na figura abaixo | ||
+ | {{fig|PF.1| Sistema viário para implantação de semáforos para controle de veículos |SemaforoAvenida2020-2.png|600 px| }} | ||
+ | |||
+ | * A descrição exata do funcionamento foi dada na aula do dia 20 abril, e dúvidas podem ser esclarecidas pelo Slack da turma. | ||
+ | |||
+ | ;Resumo de algumas especificações mínimas que o projeto devem atender: | ||
+ | |||
+ | * Serão implementados dois controladores de semáforos, cada um com dois grupos focais simples ("sinaleira de 3 lâmpadas") e um mostrador de dois dígitos que deverá mostrar o tempo de verde restante na '''Avenida Principal'''. | ||
+ | * Bônus (1 ponto) Mostrar o tempo restante de vermelho na avenida no mesmo mostrador. | ||
+ | * O tempo de verde da '''Avenida Principal''' é de 90 segundos no cruzamento com a Rua 1 e de 80 segundos no cruzamento com a Rua 2. | ||
+ | * O tempo de verde da '''Rua 1''' é de 20 segundos. | ||
+ | * O tempo de verde da '''Rua 2''' é de 20 segundos. | ||
+ | * O tempo de amarelo de todos grupos focais é de 2 segundos. | ||
+ | * Pode ser utilizado o amarelo piscante quando o semáforo estiver desativado, mas não é necessário. | ||
+ | * O controlador dos semáforos deverá ser descrito através de máquinas de estado finita com temporização (FSMt). | ||
+ | * Recomenda-se utilizar a temporização da FSM para calcular o tempo restante a ser mostrado nos mostradores de sete segmentos. | ||
+ | * O projeto deverá ser estruturado em pelo menos dois níveis hierárquicos, conforme mostram as figuras a seguir. | ||
+ | {{fig|PF.2| Top Level do Sistema de controle de veículos |TL_SemaforoAvenida2020-2.png|400 px| }} | ||
+ | {{fig|PF.3| Detalhamento do componente Semáforo |Comp_SemaforoAvenida2020-2.png|400 px| }} | ||
+ | |||
+ | ;Testes mínimos: | ||
+ | * O sistema deverá ser simulado de modo a mostrar o correto funcionamento do semáforo. | ||
+ | * Deverá ser feita uma simulação do componente Semáforo, e uma simulação do projeto completo. | ||
+ | |||
+ | ;Entregas: | ||
+ | * Arquivo QAR do projeto, contendo todos os arquivos necessário para reproduzir o projeto. | ||
+ | * Arquivos .do com os testbench para o MODELSIM; | ||
+ | * Relatório técnico contendo os resultados em no máximo 20 paginas A4, em fonte 12pt. O relatório além das tabelas com os dados de '''frequência máxima''', número de '''elementos lógicos''', número de '''pinos''', deverá conter a figura dos circuitos RTL da ENTITY top level e do componente semáforo, bem como uma explicação do seu funcionamento. Também devem ser apresentadas as simulações funcionais e uma análise textual dos resultados obtidos. | ||
+ | |||
+ | |||
+ | ;Prazos das entregas do projeto: | ||
+ | *(28/abr) Entrega final do projeto: arquivos do projeto. | ||
+ | *(29/abr) Entrega do relatório final. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ==Referências== |
Edição atual tal como às 14h42min de 20 de abril de 2021
MURAL DE AVISOS E OPORTUNIDADES DA ÁREA DE TELECOMUNICAÇÕES
Registro on-line das aulas
Unidade 1 - Introdução a disciplina
- 3 AULAS
Unidade 1 - Introdução a disciplina | ||||
---|---|---|---|---|
|
Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS
- 3 AULAS
Unidade 2 - Introdução ao VHDL e ambienta EDA - QUARTUS |
---|
Figura 2.1 - Fluxo simplificado do projeto de FPGA
library library_name;
use library_name.package_name.all;
entity entity_name is
[generic (
cons_name1: const_type const_value;
cons_name2: const_type const_value;
...
cons_nameN: const_type const_value);]
[port (
signal_name1: mode signal_type;
signal_name2: mode signal_type;
...
signal_nameN: mode signal_type);]
[declarative_part]
[begin
statement_part]
end [entity] [entity_name];
architecture arch_name of entity_name is
[declarative_part]
begin
statement_part
end [architecture] [arch_name];
library std;
use std.standard.all;
entity nand_gate is
port (a, b: in bit; x: out bit);
end entity;
architecture nome_arch of nand_gate is
begin
x <= a nand b;
end architecture;
-- Declaração das bibliotecas e pacotes
LIBRARY ieee;
USE ieee.std_logic_1164.all;
-- Especificação de todas as entradas e saídas do circuito
ENTITY flip_flop IS
PORT (d, clk, rst: IN STD_LOGIC;
q: OUT STD_LOGIC);
END;
-- Descrição de como o circuito deve funcionar
ARCHITECTURE flip_flop OF flip_flop IS
BEGIN
PROCESS (clk, rst)
BEGIN
IF (rst='1') THEN
q <= '0';
ELSIF (clk'EVENT AND clk='1') THEN
q <= d;
END IF;
END PROCESS;
END;
Figura 2.2 - Código RTL do Exemplo 2.2
Figura 2.3 - Technology Map do Exemplo 2.2
Figura 2.4 - Chip Planner do Exemplo 2.2
Figura 2.5 - RTL 4 FF
Figura 2.6 - Simulação Funcional de 4 FF 100ns Figura 2.7 - Simulação Temporal de 4 FF 100ns Note que na simulação funcional a mudança da saída Q ocorre no instante em que ocorre a borda de subida do clock ou no momento do reset. No entanto, no caso da simulação com timing, existe um atraso de ~6ns nestas mudanças. IMPORTANTE: Na prática normalmente não é necessário fazer a simulação temporal, pois através do Time Quest Report é possível verificar se o circuito atende as restrições de tempo.
create_clock -name CLK50MHz -period 50MHz [get_ports {*}]
ls /opt/altera/13.0sp1/quartus/libraries/vhdl/std
ls /opt/altera/13.0sp1/quartus/libraries/vhdl/ieee
ls /opt/altera/13.0sp1/quartus/libraries/vhdl/mentor/arithmetic (Mentor Graphics) ls /opt/altera/13.0sp1/quartus/libraries/vhdl/synopsys/ieee (Synopsys)
ls /opt/altera/16.0/quartus/libraries/vhdl/ieee/2008
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY registered_comp_add IS
PORT (clk: IN STD_LOGIC;
a, b: IN INTEGER RANGE 0 TO 7;
reg_comp: OUT STD_LOGIC;
reg_sum: OUT INTEGER RANGE 0 TO 15);
END;
ARCHITECTURE circuit OF registered_comp_add IS
SIGNAL comp: STD_LOGIC;
SIGNAL sum: INTEGER RANGE 0 TO 15;
BEGIN
comp <= '1' WHEN a>b ELSE '0';
sum <= a + b;
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk='1') THEN
reg_comp <= comp;
reg_sum <= sum;
END IF;
END PROCESS;
END;
Figura 2.10 - Código RTL do Exemplo 2.3 Note que na simulação funcional a mudança da saída Q ocorre no instante em que ocorre a borda de subida do clock ou no momento do reset. No entanto, no caso da simulação com timing, existe um atraso nestas mudanças. IMPORTANTE: Na prática normalmente não é necessário fazer a simulação temporal, pois através do Time Quest Report é possivel verificar se o circuito atende as restrições de tempo.
create_clock -name CLK50MHz -period 50MHz [get_ports {*}]
Video motivational para apreender FPGA, VHDL Microsoft's Bing* Intelligent Search with Intel® FPGAs |
Unidade 3 - Tipos de Dados e Operadores em VHDL
- 11 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: "IFSC" "teste" "teste123"
elemento ("bit") único: '0' '1' 'Z' (entre aspas simples) vetor de elementos ("bits"): "0110" "101001Z" (entre aspas duplas) vetor de 1 elemento ("bit"): "0" "1" (entre aspas duplas) inteiros: 5 1101 1102 (sem aspas)
0 -> '0' 7 (em base 2) -> "0111" ou b"0111" ou B"0111" 1023 (em base 2) -> "001111111111" ou b"1111111111" ou B"1111111111"
44 (em base 8) -> 5*8^1 + 4*8^0 -> O"54" ou o"54" 1023 (em base 8)-> 1*8^3 + 7*8^2 + 7*8^1 + 7*8^0 -> o"1777" 8#1777#
1023 (em base 16) -> 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
85 (em base 5) -> (3*5^2 + 2*5^1 + 0*5^0) -> 5#320# 1539 (em base 3) -> (2*3^2+0*3^1+1*3^0)*3^4 -> 3#201#E4
constant <constant_name> : <type> := <constant_value>;
A constant pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, PACKAGE_BODY, BLOCK, GENERATE, PROCESS, FUNCTION e PROCEDURE. -- Signal sem valor default
-- Para atribuir um valor a um signal use "<=" como operador.
signal <name> : <type>;
-- Signal com valor default
signal <name> : <type> := <default_value>;
-- Declarações comuns de signals
signal <name> : std_logic;
signal <name> : std_logic_vector(<msb_index> downto <lsb_index>);
signal <name> : integer;
signal <name> : integer range <low> to <high>;
O signal pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, BLOCK, GENERATE. Os sinais não podem ser declarados no código sequencial (PROCESS, FUNCTION e PROCEDURE), mas podem ser usados. -- Variables devem ser declarada em process ou subprogramas.
-- Para atribuir um valor a um variable use ":=" como operador.
-- Variable sem valor default.
variable <name> : <type>;
-- Variable com valor default.
variable <name> : <type> := <default_value>;
-- Declarações comuns de variables
variable <name> : std_logic;
variable <name> : std_logic_vector(<msb_index> downto <lsb_index>);
variable <name> : integer;
variable <name> : integer range <low> to <high>;
O variable (variável) só pode ser declarada e usada dentro do escopo no código sequencial (PROCESS, FUNCTION e PROCEDURE).
Exemplos de declaração de CONSTANT, SIGNAL, VARIABLE, inicializando o valor usando o agregados CONSTANT a: BIT_VECTOR(5 DOWNTO 0) := (OTHERS => '0'); -- "000000"
CONSTANT b: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', OTHERS => '1'); -- "01111111"
CONSTANT c: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', 6 DOWNTO 0 => '1'); -- "01111111"
CONSTANT d: BIT_VECTOR(7 DOWNTO 0) := "01111111";
SIGNAL e: STD_LOGIC_VECTOR(7 DOWNTO 0); -- Not initialized
SIGNAL f: STD_LOGIC_VECTOR(1 TO 8) := (2|3|8 => '1', 4 => 'Z', OTHERS => '0' ); -- "011Z0001"
VARIABLE g: BIT_VECTOR(1 TO 16); -- Not initialized
VARIABLE h: BIT_VECTOR(1 TO 16) := (1 TO 8 => '1', OTHERS => '0'); -- "1111111100000000"
A biblioteca standard.vhd define os tipos BIT, BIT_VECTOR, BOOLEAN, INTEGER, NATURAL, POSITIVE, CHARACTER, STRING. package standard is
type boolean is (false,true);
type bit is ('0', '1');
type severity_level is (note, warning, error, failure);
type integer is range -2147483647 to 2147483647;
type real is range -1.0E308 to 1.0E308;
type time is range -2147483648 to 2147483647
units
fs;
ps = 1000 fs;
ns = 1000 ps;
us = 1000 ns;
ms = 1000 us;
sec = 1000 ms;
min = 60 sec;
hr = 60 min;
end units;
subtype natural is integer range 0 to integer'high;
subtype positive is integer range 1 to integer'high;
type string is array (positive range <>) of character;
type bit_vector is array (natural range <>) of bit;
A biblioteca Std logic 1164.vhd define os tipos STD_(U)LOGIG, STD_(U)LOGIG_VECTOR. PACKAGE std_logic_1164 IS
TYPE std_ulogic IS ( 'U', -- Uninitialized
'X', -- Forcing Unknown
'0', -- Forcing 0
'1', -- Forcing 1
'Z', -- High Impedance
'W', -- Weak Unknown
'L', -- Weak 0
'H', -- Weak 1
'-' -- Don't care
);
TYPE std_ulogic_vector IS ARRAY ( NATURAL RANGE <> ) OF std_ulogic;
SUBTYPE std_logic IS resolved std_ulogic;
TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic;
A biblioteca Std logic 1164.vhd ainda define algumas funções importantes como a rising_edge que determina se um sinal está na borda de subida (usado em sinais de clock). -------------------------------------------------------------------
-- conversion functions
-------------------------------------------------------------------
FUNCTION To_bit ( s : std_ulogic; xmap : BIT := '0') RETURN BIT;
FUNCTION To_bitvector ( s : std_logic_vector ; xmap : BIT := '0') RETURN BIT_VECTOR;
FUNCTION To_StdULogic ( b : BIT ) RETURN std_ulogic;
FUNCTION To_StdLogicVector ( b : BIT_VECTOR ) RETURN std_logic_vector;
-------------------------------------------------------------------
-- edge detection
-------------------------------------------------------------------
FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
-------------------------------------------------------------------
-- edge detection
-------------------------------------------------------------------
FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS
-- altera built_in builtin_rising_edge
BEGIN
RETURN (s'EVENT AND (To_X01(s) = '1') AND
(To_X01(s'LAST_VALUE) = '0'));
END;
A biblioteca Numeric std.vhd define os tipos UNSIGNED e SIGNED. package NUMERIC_STD is
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
type SIGNED is array (NATURAL range <>) of STD_LOGIC;
A biblioteca Numeric std.vhd ainda define os operadores (abs, "+", "-", "*", "\", rem, mod, sll, slr, ror, rol), comparações ("=", '/=', ">", ">=", "<", "<=") e operadores lógicos (not, and, nand, or, nor, xor, xnor) para os tipos SIGNED e UNSIGNED. Além disso também define algumas funções muito utilizadas como: --============================================================================
-- RESIZE Functions
--============================================================================
function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;
--============================================================================
-- Conversion Functions
--============================================================================
function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
function TO_INTEGER (ARG: SIGNED) return INTEGER;
function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
Figura 3.1 - Simulação do indicador de vagas
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;
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;
x = "1----" -- não funciona em VHDL
std_match(x, "1----") -- funciona em VHDL
Ler e guardar a página sobre Aritmética com vetores em VDHL
São suportados nos tipos de dados: BIT, BIT_VECTOR, BOOLEAN, STD_(U)LOGIC, STD_(U)LOGIC_VECTOR, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para BOOLEAN_VECTOR, UFIXED, SFIXED e FLOAT. NOT AND NAND OR NOR XOR XNOR Apenas o operador NOT tem precedência sobre os demais y <= a AND b XOR c -- é equivalente a (a AND b) XOR c y <= NOT a AND b -- é equivalente a (NOT a) AND b. y <= a NAND b -- é equivalente a NOT (a AND b)
São suportados nos tipos de dados: INTEGER, NATURAL, POSITIVE, SIGNED e UNSIGNED. Com VHDL 2008 também suportado para UFIXED, SFIXED e FLOAT. soma (+) subtração (-) multiplicação (*) divisão (/) exponenciação (**) valor absoluto (ABS) resto (REM remainder) módulo (MOD) Não há restrições para síntese de circuitos com os operadores, exceto para "**" que necessita de expoente estático (a**5) ou base estática (5**a). O operador x/y é a divisão inteira com sinal.
O operador ABS x retorna o valor absoluto de x.
O operador x REM y retorna o resto de x/y com sinal de x. Esse operador realiza a operação x REM y = x - (x/y)*y.
O operador x MOD y retorna o resto de x/y com sinal de y. Esse operador realiza a operação x MOD y = x REM y + a*y, onde a = 1 quando o sinal de x é diferente do sinal de y, e a = 0 se os sinais de x e y são iguais.
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 3.2 - RTL do conversor de Binário para BCD com 2 digitos Figura 3.3 - 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;
signal a: bit_vector(7 downto 0) := "01100101"; y <= a SLL 2; -- y <= "10010100" (y <= a(5 downto 0) & "00";) y <= a SLA 2; -- y <= "10010111" (y <= a(5 downto 0) & a(0) & a(0);) y <= a ROR 2; -- y <= "01011001" (y <= a(1 downto 0) & a(7 downto 2);)
Igualdade (=) Diferença (/=) Menor que (<) Menor ou igual que (<=) Maior que (>) Maior ou igual que (>=)
Igualdade (?=) Diferença (?/=) Menor que (?<) Menor ou igual que (?<=) Maior que (?>) Maior ou igual que (?>=)
Para cada atributo existe uma descrição completa como mostrado a seguir. P'LEFT Kind: Value. Prefix: Any prefix P that is appropriate for an object with a scalar type or subtype T, or an alias thereof, or that denotes any scalar type or subtype T. Result type: Same type as T. Result: The left bound of T. A seguir estão listados alguns dos atributos mais utilizados.
P'LEFT - The left bound of T. P'RIGHT - The right bound of T. P'HIGH - The upper bound of T. P'LOW - The lower bound of T. P'ASCENDING - It is TRUE if T is defined with an ascending range; FALSE otherwise. P'LENGTH - maximum(0, T’POS(T’HIGH) – T’POS(T’LOW) + 1) P'RANGE - The range T'LEFT to T'RIGHT if the range of T is ascending, or the range T'LEFT downto T'RIGHT if the range of T is descending P'REVERSE_RANGE - The range T'RIGHT downto T'LEFT if the range of T is ascending, or the range T'RIGHT to T'LEFT if the range of T is descending T'POS(X) - The position number of the value of the parameter T'VAL(X) - The value whose position number is the universal_integer value corresponding to X.
A'LEFT [(N)] - Left bound of the Nth index range of A A'RIGHT [(N)] - Right bound of the Nth index range of A A'HIGH [(N)] - Upper bound of the Nth index range of A A'LOW [(N)] - Lower bound of the Nth index range of A. A'RANGE [(N)] - The range A'LEFT(N) to A'RIGHT(N) if the Nth index range of A is ascending, or the range A'LEFT(N) downto A'RIGHT(N) if the Nth index range of A is descending A'REVERSE_RANGE [(N)] - The range A'RIGHT(N) downto A'LEFT(N) if the Nth index range of A is ascending, or the range A'RIGHT(N) to A'LEFT(N) if the Nth index range of A is descending. A'LENGTH [(N)] - Number of values in the Nth index range A'ASCENDING [(N)] - TRUE if the Nth index range of A is defined with an ascending range; FALSE otherwise.
S'EVENT - A value that indicates whether an event has just occurred on signal S. S'LAST_VALUE - For a signal S, if an event has occurred on S in any simulation cycle, S'LAST_VALUE returns the value of S prior to the update of S in the last simulation cycle in which an event occurred; otherwise, S'LAST_VALUE returns the current value of S.
E'SIMPLE_NAME - The simple name, character literal, or operator symbol of the named entity
attribute attribute_name: attribute_type;
attribute attribute_name of entity_tag [signature]: entity_class is value;
A retirada de fatias (SLICES) dos ARRAYs só pode ser feita se o array foi definido com um vetor de vetores (1Dx1D ou 1Dx1Dx1D). Ainda assim é necessário respeitar a ordem dos índices do VETOR. No caso abaixo é ascendente (TO), e dentro dos limites (1 to 4). type a1Dx1D_bit is array (1 to 3) of BIT_VECTOR(1 to 4);
type a2D_bits is array (1 to 3, 1 to 4) of bit; type a3D_bits is array (1 to 3, 1 to 4, 1 to 2) of bit;
slice3 <= table(row, 1) & table(row, 2) & & table(row, 3) & & table(row, 4);
slice4 <= table(1, column) & table(2, column) & table(3, column);
gen1 : for j in 1 to 4 generate
slice3(j) <= table(row, j);
end generate;
gen2 : for i in 1 to 3 generate
slice4(i) <= table(i, column);
end generate;
-----Package:------------
-- File: my_pkg.vhd
-------------------------
package my_data_types is
type a1Dx1D_bit_vector is array (0 to 3) of BIT_VECTOR(7 downto 0);
end my_data_types;
-----Main code: --------
-- File: my_pkg.vhd
-------------------------
use work.my_data_types.all;
entity mux1Dx1D is
port (
x : in a1Dx1D_bit_vector;
sel : integer range 0 to 3;
y : out BIT_VECTOR(7 downto 0)
);
end entity;
architecture pedroni of mux1Dx1D is
begin
y <= x(sel);
end architecture;
Ver pag. 60 a 73 de [2]
Enquanto que em um ARRAY todos os elementos devem ser obrigatoriamente do mesmo tipo, em um RECORD (Registro) os elementos podem ser de tipos diferentes. type memory_access is record
address : integer range 0 to 255;
block : integer range 0 to 3;
data : BIT_VECTOR(15 downto 0);
end record;
--Escrita no RECORD
constant endereco : memory_access := (34, 3, "010011110101011");
--Acesso ao RECORD
signal address_lido : integer range 0 to 255;
signal block_lido : integer range 0 to 3;
signal data_lido : bit_vector(15 downto 0);
address_lido <= endereco.address;
block_lido <= endereco.block;
data_lido <= endereco.data;
entity record_example is
port (
flag : out BIT_VECTOR(1 to 4);
sum : out natural range 0 to 15
);
end entity;
architecture record_example of record_example is
type pair is record
a, b : natural range 0 to 7;
end record;
type stack is array (1 to 4) of pair;
constant matrix : stack := ((1, 2), (3, 4), (5, 6), (7, 0));
begin
gen : for i in 1 to 4 generate
flag(i) <= '1' when matrix(i).a > matrix(i).b else '0';
end generate;
sum <= matrix(1).a + matrix(1).b;
end architecture;
A declaração de SUBTYPE é usada para restringir as declarações de TYPE. Abaixo estão alguns exemplos. subtype natural is integer range 0 to integer'HIGH;
subtype positive is integer range 1 to integer'HIGH;
subtype my_integer is integer range - 32 to 31;
A declaração ALIAS define um nome alternativo para uma entidade ou objeto. ALIAS new_name [: specifications] IS original_name [signature];
SIGNAL data_bus: STD_LOGIC_VECTOR(31 DOWNTO 0);
--bus1 is a new name for data_bus:
ALIAS bus1 IS data_bus;
--bus2 is a new name for data_bus, but with a modified range:
ALIAS bus2: STD_LOGIC_VECTOR(32 DOWNTO 1) IS data_bus;
--bus3 is another name for data_bus, with an ascending range:
ALIAS bus3: STD_LOGIC_VECTOR(1 TO 32) IS data_bus;
--upper_bus1 is a new name for the upper half of data_bus
ALIAS upper_bus1 IS data_bus(31 DOWNTO 16);
--upper_bus2 is a new name for the upper half of data_bus, but
--with a modified range:
ALIAS upper_bus2: STD_LOGIC_VECTOR(17 TO 32) IS data_bus(31 DOWNTO 16);
--lower_bus1 is a new name for the lower half of data_bus
ALIAS lower_bus1 IS data_bus(15 DOWNTO 0);
--lower_bus2 is a new name for the lower half of data_bus, but
--with a modified range:
ALIAS lower_bus2: STD_LOGIC_VECTOR(1 TO 16) IS data_bus(15 DOWNTO 0);
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;
function "+" (a : integer; b : bit) return integer is
begin
if (b = '1') then return a + 1;
else
return a;
end if;
end "+";
function "+" (a : integer; b : std_logic) return integer is
begin
if (b = '1') then return a + 1;
else
return a;
end if;
end "+";
Figura 3.7 - Conversões entre tipos Integer, Unsigned, Signed, Std_logic_vector
a_UNS <= unsigned(a_SLV); a_SIG <= signed(a_SLV);
a_INT <= to_integer(a_UNS)); a_INT <= to_integer(a_SIG));
a_SLV <= std_logic_vector(a_UNS); a_SLV <= std_logic_vector(a_SIG);
a_UNS <= to_unsigned(a_INT,NBITS)); a_SIG <= to_signed(a_INT, NBITS));
function "+" (L, R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
-- Result: Adds two UNSIGNED vectors that may be of different lengths.
function "-" (L, R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
-- Result: Subtracts two UNSIGNED vectors that may be of different lengths.
function "*" (L, R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0).
-- Result: Performs the multiplication operation on two UNSIGNED vectors
-- that may possibly be of different lengths.
function "/" (L, R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
-- Result: Divides an UNSIGNED vector, L, by another UNSIGNED vector, R.
-- NOTE: If second argument is zero for "/" operator, a severity level of ERROR is issued.
function "rem" (L, R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
-- Result: Computes "L rem R" where L and R are UNSIGNED vectors.
function "mod" (L, R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
-- Result: Computes "L mod R" where L and R are UNSIGNED vectors.
|
- Recesso entre dia 24/dez/2020 e 01/02/2021
Boas férias a todos. Nos encontramos no retorno.
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>;
Warning (13012): Latch ... has unsafe behavior
<optional_label>: with <expression> select
<target> <=
<value> when <choices>,
<value> when <choices>,
<value> when <choices>,
...
<value> when others;
Error (10313): VHDL Case Statement error ...: Case Statement choices must cover all possible values of expression
configuration which_mux of mux4x1 is
-- for operators_only end for;
-- for operators_only_alias 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;
-------------------------
-- File: gray2bin.vhd --
-------------------------
entity gray2bin is
generic (N : natural := 4 )
port
(
g : in std_logic_vector(____)
b : out std_logic_vector(____)
)
end entity
architecture ifsc_v1 of ____ is
begin
end architecture
architecture ifsc_v2 of ____ is
begin
end architecture
----------------------
-- File: alu.vhd --
----------------------
entity alu is
generic (N : natural := 8);
port
(
a, b : in std_logic(? downto 0);
cin : in std_logic;
opcode : in std_logic(? downto 0);
y : out std_logic(? downto 0)
);
end entity;
architecture alu of alu is
begin
end architecture;
Figura 3.9 - Unidade de Lógica e Aritmética
|
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];
--Flip Flop tipo D com reset assincrono, sensivel a borda de subida.
process (clock,reset)
begin
if (reset = '1') then
q <= '0';
-- elsif (clock'event and clock = '1') then or
elsif (rising_edge(clock)) then
q <= d;
end if;
end process;
--Flip Flop tipo D com preset assincrono e sinal de enable, sensivel a borda de descida.
process (clock, preset)
begin
if (preset = '1') then
q <= '1';
elsif (falling_edge(clock)) then
if (enable = '1') then
q <= d;
end if;
end if;
end process;
--Latch tipo D com reset assincrono.
process (enable, reset, d)
begin
if (reset = '1') then
d <= '0';
elsif (enable='1')) then
q <= d;
end if;
end process;
-- Flip Flop tipo D com reset síncrono sensível a borda de subida.
-- Modifique a descrição para que o reset_ass seja assíncrono e reset_sinc seja síncrono.
-- Note que a função rising_edge(clock) é equivalente a (clock'event and clock'last_value = '0' and clock = '1'))
process (clock, reset)
begin
if (reset = '1') then
q <= '0';
elsif (clock'event and clock'last_value = '0' and clock = '1')) then
q <= d;
end if;
end process;
Figura 4.1 - RTL do registrador de deslocamento (Ex.6.3)
entity shift_reg4_right is
port
(
din, clk, rst : in std_logic;
dout : out std_logic
);
end entity;
architecture ifsc of shift_reg4_right is
begin
end architecture;
entity shift_reg_right is
generic (N : integer := 4);
port
(
din, clk, rst : in std_logic;
dout : out std_logic
);
end entity;
architecture ifsc of shift_reg_right is
begin
end architecture;
entity shift_reg_right is
generic (N : integer := 4);
port
(
din, clk, rst : in std_logic;
dout : out std_logic
);
end entity;
architecture ifsc of shift_reg_right is
begin
process (clk, rst)
variable q : std_logic_vector (N-1 downto 0);
begin
if (rst = '1') then
q := (others => '0');
elsif (clk'EVENT and clk = '1') then
q := din & q (N-1 downto 1);
end if;
dout <= q(0);
end process;
end architecture;
Aproveitando a versão 3 ou 2 do Shift Register da aula anterior, projete e faça a simulação dos dois circuitos indicados a seguir:
Figura 4.2 - RTL do embrião de um conversor serial para paralelo
Figura 4.3 - Simulação funcional do embrião de um conversor serial para paralelo
entity serial2parallel is
port
(
clk, rst : in std_logic;
SerialIn : in std_logic;
DataOut : out std_logic_vector(N-1 downto)
);
end entity;
architecture ifsc of serial2parallel is
begin
end architecture;
Figura 4.4 - Simulação funcional do embrião de um conversor paralelo para serial
Figura 4.5 - Simulação funcional do embrião de um conversor paralelo para serial
entity parallel2serial is
port
( clk, rst : in std_logic;
Load : in std_logic;
DataIn : in std_logic_vector(N-1 downto);
SerialOut : out std_logic
);
end entity;
architecture ifsc of parallel2serial is
begin
end architecture;
Instruções do tipo LOOP: LOOP incondicional, FOR-LOOP, WHILE-LOOP, NEXT, EXIT
[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;
entity leading_zeros is
generic (N : natural := 8);
port
( Vin : in std_logic_vector(0 to N-1);
count : out integer range 0 to N
);
end entity;
architecture ____ of leading_zeros is
begin
process (data)
variable count : integer ____ 0 to N
begin
count := 0;
for i ___ data'range ____
case data(i) is
when '0' => count := count + 1;
when _____ => exit;
end ___
end ____
zeros <= count;
end process;
end _______;
entity carry_ripple_adder is
generic (N : integer := 4);
port (
a, b : std_logic_vector (N-1 downto 0);
cin : std_logic
s : out std_logic_vector (N downto 0);
cout : out std_logic;
);
end entity;
architecture estrutural of carry_ripple_adder
begin
-- Uso de um codigo sequencial para geracao de um circuito combinacional
process (a, b, cin)
variable c : std_logic_vector(N downto);
begin
c(0) := cin;
for i in 0 to N - 1 loop
-- Codigo de um full adder
-- soma de dois bits e carry_in do full adder anterior
s(i) <= a(i) xor b(i) xor c(i);
-- geraao do carry_out para o proximo full adder
c(i + 1) := (a(i) and b(i)) or (a(i) and c(i)) or (b(i) and c(i));
end loop;
cout <= c(N);
end process;
end architecture;
[rótulo:] WAIT UNTIL <condition>;
[rótulo:] WAIT ON sensitivity_list;
[rótulo:] WAIT FOR time_expression;
entity timer0_9 is
port (
clk1seg,rst: in std_logic;
count_out : out std_logic_vector(3 downto 0);
ssd_out : out std_logic_vector(6 downto 0)
);
end entity;
architecture ifsc_v1 of timer0_9 is
begin
process (rst, clk1seg)
-- processo do contador de 0 a 9
end process;
process (count)
begin
-- processo do codificador de binario para display de sete segmentos
end process;
end architecture;
A simulação funcional do circuito deverá produzir uma saída semelhante a mostrada abaixo: Figura 4.6 - simulação funcional do timer0_9 A simulação com timing do circuito deverá produzir uma saída semelhante a mostrada abaixo: Figura 4.7 - simulação com timing do timer0_9 Depois acrescentar a esse circuito um módulo que permita a partir de um sinal de clock com frequência de fclk = 50MHz (T = 20 ns), obter um clock de f = 1 Hz (T = 1 s) process (rst, clk50MHz)
-- processo do divisor de clock de 50MHz para 1 Hz
end process;
Implementar no FPGA o circuito com contador de 0 a 9 segundos com saída SSD e clk de entrada de 50MHz.
ssd_out <= not ssd;
Uso do Modelsim para simulação funcional.
AE5
|
Unidade 6 - Projeto a nível de Sistema
- 4 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);
AE6
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 síntese e/ou simulação. Pode ser condicional ou incondicional (condição_booleana = FALSE). A sintaxe da instrução é: [rótulo:] assert condição_booleana
[report mensagem]
[severity nivel_severidade];
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" [9].
function nome_funçao (lista_parametros_entrada) return tipo_saida is
declarações
begin
afirmações sequenciais
end function;
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. 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;
procedure nome_procedimento (lista_parâmetros_entrada, lista_parâmetros_saída) is
declarações
begin
afirmações sequenciais
end procedure;
-- FILE: comparator.vhd
-- Fonte: PEDRONI, Volnei A. Circuit Design and Simulation with VHDL; 2 ed. Massachusetts-EUA:MIT, 2010.
library ieee;
use ieee.numeric_std.all;
use work.my_package.all;
entity organizer is
generic (size : natural := 3);
port
(
x : in UNSIGNED(2 to 5);
y : out UNSIGNED(size - 1 downto 0)
);
end entity;
architecture organizer of organizer is
begin
y <= order_and_fill(x, size);
end architecture;
-- FILE: my_pkg.vhd
-- Fonte: PEDRONI, Volnei A. Circuit Design and Simulation with VHDL; 2 ed. Massachusetts-EUA:MIT, 2010. 608 p. ISBN 9780262014335
library ieee;
use ieee.numeric_std.all;
package my_package is
function order_and_fill (input : UNSIGNED; bits : natural) return UNSIGNED;
end package;
package body my_package is
function order_and_fill (input : UNSIGNED; bits : natural) return UNSIGNED is
variable a : UNSIGNED(input'LENGTH - 1 downto 0);
variable result : UNSIGNED(bits - 1 downto 0);
begin
assert (input'LENGTH <= bits)
report "Improper input size!"
severity FAILURE;
if (input'LEFT > input'RIGHT) then
a := input;
else
for i in a'range loop
a(i) := input(input'LEFT + i);
end loop;
end if;
if (a'LENGTH < bits) then
result(bits - 1 downto a'LENGTH) := (others => '0');
result(a'LENGTH - 1 downto 0) := a;
else
result := a;
end if;
return result;
end function;
end package body;
Figura 6.1 - Fluxograma da PROCEDURE min_max -- FILE: comparator.vhd
-- Fonte: PEDRONI, Volnei A. Circuit Design and Simulation with VHDL; 2 ed. Massachusetts-EUA:MIT, 2010.
use work.my_package.all;
entity comparator is
port
(
a, b, c : in integer range 0 to 255;
min, max : out integer range 0 to 255
);
end entity;
architecture comparator of comparator is
begin
min_max(a, b, c, min, max);
end architecture;
-- FILE: my_pkg.vhd
-- Fonte: PEDRONI, Volnei A. Circuit Design and Simulation with VHDL; 2 ed. Massachusetts-EUA:MIT, 2010.
package my_package is
procedure min_max (
signal a, b, c : in integer;
signal min, max : out integer
);
end package;
package body my_package is
procedure min_max (
signal a, b, c : in integer range 0 to 255;
signal min, max : out integer range 0 to 255) is
begin
if (a >= b) then
if (a >= c) then
max <= a;
if (b >= c) then
min <= c;
else
min <= b;
end if;
else
max <= c;
min <= b;
end if;
else
if (b >= c) then
max <= b;
if (a >= c) then
min <= c;
else min <= a;
end if;
else
max <= c;
min <= a;
end if;
end if;
end procedure;
end package body;
|
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";
-- ATTRIBUTE SYN_ENCODING OF state : TYPE IS "safe";
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 > ;
Figura 7.1 - Exemplo de diagrama de estados de uma FSM Fig11.1(a) e implementação em hardware da FSM Fig11.2(a)
Figura 7.2 - FSM - Máquina de vender doces (diagrama de estados) Figura 7.3 - FSM - Máquina de vender doces (diagrama de estados com default
Figura 7.4 - FSM - Máquina de vender doces (simulação)
Figura 7.5 - FSM - alarme (oscilando entre os estados quando remoto é 1)
Figura 7.6 - FSM - alarme (solução com flag)
Figura 7.7 - FSM - alarme (solução com estados de WAIT) Figura 7.8 - Simulação da FSM - alarme (solução com estados de WAIT)
ATUAL
Figura 7.9 - Tipos de FSM (Condicional, Temporizada e Hibrida)
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 > ;
Figura 7.10 - Diagrama de estados do controlador de semáforo Figura 7.11 - Simulação do controlador de semáforo no Modelsim
|
Avaliações
Nas avaliações A1 e A2 são com consulta apenas as folhas de consulta entregues:
- VHDL Quick Reference - SynthWorks
- VHDL Types and Operators Quick Reference - SynthWorks
- ModelSim Quick Reference - SynthWorks
- Tabelas das figuras 3.6, 3.10 e 4.1 do livro do Pedroni.
- Arquivo:Numeric std conversions.png
- Dica use também como fonte de consulta os templates do Quartus.
- Ao final das avaliações o aluno deverá enviar a avaliação para a plataforma Moodle com os arquivos solicitados.
Projeto Final (PF)
- O projeto final é uma atividade de avaliação que será desenvolvida de forma individual. Consiste no desenvolvimento de um sistema que aplica os conhecimento adquiridos durante o semestre. A avaliação do projeto final corresponde a 36% do peso no conceito final. São avaliados no projeto final os quesitos:
- 1) Sistema desenvolvido (projeto, simulação e realização, demonstração do hardware); (18%)
- 2) Relatório com a documentação completa do projeto; (18%)
Referências
- ↑ 1,0 1,1 1,2 1,3 1,4 PEDRONI, Volnei A. Eletrônica digital moderna e VHDL; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. . ISBN 9788535234657
- ↑ 2,00 2,01 2,02 2,03 2,04 2,05 2,06 2,07 2,08 2,09 2,10 2,11 2,12 2,13 2,14 2,15 2,16 2,17 2,18 2,19 2,20 2,21 2,22 2,23 2,24 2,25 2,26 2,27 2,28 2,29 PEDRONI, Volnei A. Circuit Design and Simulation with VHDL; 2ª ed. Massachusetts-EUA:MIT, 2010. 608 p. ISBN 9780262014335