ELD129003-Engtelecom (Diário) - Prof. Marcos Moecke: mudanças entre as edições

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
Moecke (discussão | contribs)
Moecke (discussão | contribs)
 
(315 revisões intermediárias por 2 usuários não estão sendo mostradas)
Linha 4: Linha 4:
{{collapse top | expand=true | Unidade 1 - Aula inicial, Introdução a disciplina}}
{{collapse top | expand=true | Unidade 1 - Aula inicial, Introdução a disciplina}}


;Encontro 1 (16 fev):
;Encontro 1 (12 ago.):
* A '''[[ELD2-EngTelecom (Página) | página da UC]]''' contém os materiais que não alteram entre semestre.
* A '''[[ELD2-EngTelecom (Página) | página da UC]]''' contém os materiais que não alteram entre semestre.
* Relação com as outras UCs do '''Eixo Sistemas Computacionais (Marrom)'''. Ver [https://docente.ifsc.edu.br/moecke/ppc-engtelecom/PPC2023/ grafo do curriculo]
* Relação com as outras UCs do '''Eixo Sistemas Computacionais (Marrom)'''. Ver [https://docente.ifsc.edu.br/moecke/ppc-engtelecom/PPC2023/ grafo do curriculo]
Linha 18: Linha 18:
*Utilizaremos durante as aulas algumas ferramentas computacionas como o site do [https://www.falstad.com/circuit/circuitjs.html Falstad] para entender circuitos digitais e fazer simulações básicas.
*Utilizaremos durante as aulas algumas ferramentas computacionas como o site do [https://www.falstad.com/circuit/circuitjs.html Falstad] para entender circuitos digitais e fazer simulações básicas.
*Também utilizaremos os softwares '''Quartus Light''' e '''ModelSim''' instalados nas maquinas do laboratório para praticar a parte de programação de hardware (descrição de hardware).  Esses softwares também podem ser usados através da '''[[Acesso ao IFSC-CLOUD (NUVEM)|Nuvem do IFSC]]'''..
*Também utilizaremos os softwares '''Quartus Light''' e '''ModelSim''' instalados nas maquinas do laboratório para praticar a parte de programação de hardware (descrição de hardware).  Esses softwares também podem ser usados através da '''[[Acesso ao IFSC-CLOUD (NUVEM)|Nuvem do IFSC]]'''..
*Para a prática de implementação dos circitos em dispositivos lógicos utilizaremos os kits de FPGA disponíveis no LabSiDi. Ver  [[Media:ManualDE2-115.pdf | User Manual da DE2-115]], e [[Media:ManualMercurio.pdf | Manual do Usuário da Mercúrio IV]].
    
    
;LER PARA O PRÓXIMO ENCONTRO:
;LER PARA O PRÓXIMO ENCONTRO:
*Revisão dos conceitos sobre circuitos combinacionais vistos em CIL/ELD1
*Revisão dos conceitos sobre circuitos combinacionais vistos em CIL/ELD1
*Para alunos que não cursaram ELD1 (não conhecem VHDL), irei fornecer uma sequência de estudos para conhecer melhor as instruções concorrentes do VHDL.
*Para alunos que não cursaram ELD1 (não conhecem VHDL), irei fornecer uma sequência de estudos para conhecer melhor as instruções concorrentes do VHDL.
*Ler [https://moodle.ifsc.edu.br/pluginfile.php/336168/mod_resource/content/1/Introdu%C3%A7%C3%A3o%20a%20linguagem%20de%20descri%C3%A7%C3%A3o%20de%20hardware.pdf Introdução a linguagem de descrição de hardware (DHL)]
*Ler página [[Preparando para gravar o circuito lógico no FPGA]]
*Ler slides [https://drive.google.com/file/d/1VNUqU3nBkNWv3w-yT3HT18eY878JcgXz/view?usp=drive_link Introdução a linguagem de descrição de hardware (DHL)]
{{collapse bottom}}
{{collapse bottom}}


===Unidade REV - PRIMEIRO CONTATO COM VHDL ===
===Unidade REV - PRIMEIRO CONTATO COM VHDL ===
* 3 ENCONTROS
{{collapse top | Unidade REV - PRIMEIRO CONTATO COM VHDL}}


;Encontro 2 (20 fev):
* 5 ENCONTROS
* [https://moodle.ifsc.edu.br/pluginfile.php/336168/mod_resource/content/1/Introdu%C3%A7%C3%A3o%20a%20linguagem%20de%20descri%C3%A7%C3%A3o%20de%20hardware.pdf Introdução a linguagem de descrição de hardware (DHL)]
{{collapse top | expand=true | Unidade REV - PRIMEIRO CONTATO COM VHDL}}
<!--
;Nivelamento 1:
* [https://wiki.sj.ifsc.edu.br/images/7/75/Introdu%C3%A7%C3%A3o_a_linguagem_de_descri%C3%A7%C3%A3o_de_hardware.pdf Introdução a linguagem de descrição de hardware (DHL)]


* Estrutura do código VHDL
* Estrutura do código VHDL
Linha 67: Linha 70:
</syntaxhighlight>
</syntaxhighlight>


*[[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]]


*[[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]]
;Nivelamento 2:
*Descrição do harware utilizando código VHDL no Quartus.
*Rever a IDE do Quartus
*Realizar análise e síntese.
*Obter Diagrama RTL e Technology Map do circuito
*Realizar simulação funcional com ModelSim
*Conhecer a IDE do ModelSim
*Seguir o procedimento descrito em [[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]]


;PARA O PRÓXIMO ENCONTRO:
;PARA O PRÓXIMO ENCONTRO:
Linha 77: Linha 88:
* Para conhecer um pouco mais da linguagem VHDL, ler [https://pt.wikipedia.org/wiki/VHDL VHDL] ou [https://en.wikipedia.org/wiki/VHDL VHDL.en].  A maioria dessas instruções serão tratadas posteriormente.
* Para conhecer um pouco mais da linguagem VHDL, ler [https://pt.wikipedia.org/wiki/VHDL VHDL] ou [https://en.wikipedia.org/wiki/VHDL VHDL.en].  A maioria dessas instruções serão tratadas posteriormente.


;Encontro 3 (23 fev):
;Nivelamento 3- Simulação:
*Descrição do harware utilizando código VHDL no Quartus.
*[[Como arquivar um projeto]]
*Rever a IDE do Quartus
*[[Simulação Funcional usando o ModelSim]];
*Realizar análise e síntese.
 
*Obter Diagrama RTL e Technology Map do circuito
;Nivelamento 4 - Circuitos aritméticos:
*Realizar simulação funcional com ModelSim
*Circuitos aritméticos: somadores, incrementador, decrementador, complemento de dois, multiplicador, comparadores
*Conhecer a IDE do ModelSim
:* [https://drive.google.com/file/d/1kql0io2sh9Mp4FfnqpEPrdUFkVhHBx6_/view?usp=drive_link slides]
*Seguir o procedimento descrito em [[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]]
:* Incrementador de 4 bits [https://tinyurl.com/2b2feccq] [https://tinyurl.com/2xzje3w6]
:* Decrementador de 4 bits [https://tinyurl.com/2aks3mgp] [https://tinyurl.com/22c8v57r]
:* Somador completo [https://tinyurl.com/yqkt49kl]
:* Somador de 4 bits [https://tinyurl.com/yucqnkwz]
:* Complemento de dois de 4 bits [https://tinyurl.com/23532lga]


;Encontro 4 (27 fev):
*Usando o tipo '''integer'''
;[[Como arquivar um projeto]]:
Para implementar circuitos aritméticos, ao invés de se descrever o circuito com portas lógicas conforme mostrado para somadores, subtratores, comparadores e multiplicadores, deve-se utilizar os operadores aritméticos, e o compilador realizará a escolha do melhor circuito para cada caso.  Inicialmente apresentamos alguns exemplos utilizando dados do tipo '''integer'''.


;Conhecer instruções WHEN_ELSE, WITH_SELECT, CONFIGURATION:
Para o uso do tipo integer, se não houver limitação da faixa de valores, o compilador entenderá que os sinais devem ter 32 bits, o que gera circuitos muito maiores que normalmente necessário. Assim, ao usar as entradas e saidas como integer sem range, o diagrama RTL mostrará que o circuito foi construido com 32 bits [31..0]. Nos dispositivos da familia Cyclone IV E serão utilizados 32 elementos lógicos para tal circuito.


Para ilustrar essas instruções utilizaremos o exemplo de um Mux4x1.  Um multiplexador digital de N entradas e 1 saída, frequentemente abreviado como MUX N:1, é um circuito digital muito utilizado para rotear sinais digitais. Ele desempenha a função de selecionar uma das entradas para ser encaminhada para a saída com base em um sinal de seleção (ou controle).
<syntaxhighlight lang=vhdl>
entity somador is
port (
a, b : in integer;
s : out integer;
end entity;


{{collapse top | Mux2x1}}
architecture ifsc of somador is
A tabela verdade que descreve um MUX2:1 é mostrada abaixo:
begin
<center>
s <=  a + b;
{| class="wikitable" style="text-align:center;"
end architecture;
|- style="font-weight:bold;"
</syntaxhighlight>
! X1
 
! X0
{{fig|4.1|Código RTL do somador com tipo integer sem range| RTL_somadorv1.png| 300 px |}}
! Sel
{{fig|4.2|Technology Map do somador com tipo integer sem range| TM_somadorv1.png| 1000 px |}}
! style="background-color:#c0c0c0;" | Y
 
|-
Por isso, o uso correto do tipo integer, exige que se limite a faixa de valores ('''range 0 to 15'''), o que fará com que o compilador atribua para os sinais a quantidade correta de bits, gerando circuitos de tamanho adequado.
| 0
 
| 0
Assim, ao usar as entradas e saidas como integer com '''range 0 to 15''', o diagrama RTL mostrará que o circuito foi construido com 4 bits [3..0]. Nos dispositivos da familia Cyclone IV E serão utilizados 4 elementos lógicos para tal circuito.
| 0
 
| style="background-color:#c0c0c0;" | 0
<syntaxhighlight lang=vhdl>
|-
entity somador is
| 0
port (
| 0
a, b : in integer range 0  to 15;  
| 1
s : out integer range 0  to 15);
| style="background-color:#c0c0c0;" | 0
end entity;
|-
 
| 0
architecture ifsc of somador is
| 1
begin
| 0
s <= a + b;
| style="background-color:#c0c0c0;" | 1
end architecture;
|-
</syntaxhighlight>
| 0
 
| 1
{{fig|4.3|Código RTL do somador com tipo integer com range| RTL_somadorv2.png| 300 px |}}
| 1
{{fig|4.4|Technology Map do somador com tipo integer com range| TM_somadorv2.png| 600 px |}}
| style="background-color:#c0c0c0;" | 0
 
|-
Para fazer uma subtração, basta trocar o operador "+" pelo "-", e o compilador irá implementar um subtrator realizando o complemento 2 da entrada b.
| 1
 
| 0
<syntaxhighlight lang=vhdl>
| 0
entity subtrator is
| style="background-color:#c0c0c0;" | 0
port (
|-
a, b : in integer range 0  to 15;  
| 1
s : out integer range 0 to 15);
| 0
end entity;
| 1
 
| style="background-color:#c0c0c0;" | 1
architecture ifsc of subtrator is
|-
begin
| 1
s <= a - b;
| 1
end architecture;
| 0
</syntaxhighlight>
| style="background-color:#c0c0c0;" | 1
 
|-
{{fig|4.5|Código RTL do subtrator com tipo integer com range| RTL_subtratorv1.png| 300 px |}}
| 1
Note nesta figura que as entradas b[3..0] são conectadas ao B[4..1] do somador, e que o B[0] é conectado ao Vcc ("1").  O mesmo ocorre com a entrada A.  Ao mesmo tempo a entrada b é invertida, gerando assim o complemento de dois dessa entrada. Assim para realizar uma subtração pode ser utilizado o mesmo circuito do somador.
| 1
 
| 1
Para fazer um incrementador, um dos fatores do somador é substituído por '1' e o compilador irá implementar um circuito incrementador.
| style="background-color:#c0c0c0;" | 1
 
|}
<syntaxhighlight lang=vhdl>
</center>
entity incrementador is
port (
a : in integer range 0  to 15;  
inc : out integer range 0  to 15);
end entity;


O MUX2:1 também pode ser representado de forma resumida por:
architecture ifsc of incrementador is
<center>
begin
{| class="wikitable" style="text-align:center;"
inc <= a + 1;
|- style="font-weight:bold;"
end architecture;
! X1
</syntaxhighlight>
! X0
! Sel
! style="background-color:#c0c0c0;" | Y
|-
| -
| X0
| 0
| style="background-color:#c0c0c0;" | X0
|-
| X1
| -
| 1
| style="background-color:#c0c0c0;" | X1
|}
</center>
Onde o X0 e X1 na entrada podem assumir os valores 0 ou 1, e o simbolo "-" corresponde ao ''don't care'' (em VDHL)


A função booleana que descreve a operação de um MUX 2:1 pode ser representada da seguinte forma:
{{fig|4.6|Código RTL do incrementador com tipo integer com range| RTL_incrementadorv1.png| 300 px |}}


Note que no incrementador apenas a segunda entrada do módulo RTL somador passa a ter um valor fixo '1'.  Isso faz com que o hardware necessário para efetuar a soma (+1) é reduzido.


<math>  Y =  \overline{Sel} . X0 + Sel . X1 </math>


Onde Y é a saída; Sel é o sinal de seleção; X0 e X1 são as entradas.
Para fazer o decrementador, um dos fatores do somador é substituído por '-1' e o compilador irá implementar um circuito decrementador.
{{collapse bottom}}


{{collapse top | expand=false |Mux4x1}}
<syntaxhighlight lang=vhdl>
O MUX4:1 pode ser representado de forma resumida pela tabela verdade:
entity decrementador is
port (
a : in integer range 0  to 15;
dec : out integer range 0  to 15);
end entity;
 
architecture ifsc of decrementador is
begin
dec <=  a - 1;
end architecture;
</syntaxhighlight>
 
{{fig|4.7|Código RTL do decrementador com tipo integer com range| RTL_decrementadorv1.png| 300 px |}}
Note que no decrementador apenas a segunda entrada do módulo RTL somador passa a ter um valor fixo, mas também nas duas entradas o sinal A(0) e B(0) recebem o valor fixo '1', para produzir um ''carry_in'' para a soma do bit A(1) com B(1).
 
Para fazer uma multiplicação, basta usar o operador "*" e o compilador irá implementar um multiplicador. Neste caso para evitar o overflow é importante definir o range da saída com um tamanho suficiente para comportar o maior produto.
 
<syntaxhighlight lang=vhdl>
entity multiplicador is
port (
a, b : in integer range 0  to 15;
s : out integer range 0 to 15*15);
end entity;
 
architecture ifsc of multiplicador is
begin
s <=  a * b;
end architecture;
</syntaxhighlight>


<center>
{{fig|4.6|Código RTL do multiplicador com tipo integer com range| RTL_multiplicadorv1.png| 300 px |}}
{| class="wikitable" style="text-align:center;"
 
|- style="font-weight:bold;"
Note que esse circuito no Cyclone IV E necessita de 31 elementos lógicos, e  no caso em que multiplicador tem  entradas com 4 bits [3..0], a saída terá 8 bits [7..0]. Caso a saída não tenha a quantidade suficiente de bits, haverá ''overflow'' e a resultado poderá estar incorreto.
! colspan="4" | Entradas
 
! colspan="2" | Seleção
Para fazer uma divisão, basta usar o operador "/" e o compilador irá implementar um divisor inteiro. O tamanho do quociente deve ser igual ao dividendo.
! Saída
 
|- style="font-weight:bold;"
<syntaxhighlight lang=vhdl>
| X3
entity divisor is
| X2
port (
| X1
dividendo : in integer range 0 to 15;
| X0
divisor : in integer range 0 to 3;
| Sel1
quociente : out integer range 0  to 15;
| Sel0
resto : out integer range 0  to 3
| style="background-color:#c0c0c0;" | Y
);
|-
 
| -
end entity;
| -
 
| -
architecture ifsc of divisor is
| X0
begin
| 0
quociente <= dividendo / divisor;
| 0
resto <=  dividendo rem divisor;
| style="background-color:#c0c0c0;" | X0
end architecture;
|-
</syntaxhighlight>
| -
 
| -
{{fig|4.8|Código RTL do divisor com tipo integer com range| RTL_divisorv1.png| 300 px |}}
| X1
 
| -
Multiplicações e divisões por potências de 2 (2, 4, 8, 16, ... $2^N$) não necessitam de nenhum elemento lógico pois podem ser implementados pelo simples deslocamento dos signais.
| 0
 
| 1
{{fig|4.8|Código RTL do multiplicador por 4| RTL_multiplicador4.png| 300 px |}}
| style="background-color:#c0c0c0;" | X1
|-
| -
| X2
| -
| -
| 1
| 0
| style="background-color:#c0c0c0;" | X2
|-
| X3
| -
| -
| -
| 1
| 1
| style="background-color:#c0c0c0;" | X3
|}
</center>
A função booleana que descreve a operação de um MUX 4:1 pode ser representada da seguinte forma:


<math> Y = X0 . \overline{Sel1} . \overline{Sel0} + X1 . \overline{Sel1} . Sel0 +  X2 . Sel1 . \overline{Sel0} + X3 . Sel1 . Sel0  </math>
{{fig|4.9|Código RTL do divisor por 2| RTL_divisor2.png| 300 px |}}
{{collapse bottom}}


Dada a função booleana do MUX4:1 é simples para descreve-lo em VHDL utilizando apenas operadores lógicos.
'''ATENÇÃO:'''  Multiplicações por constantes não utilizam os multiplicadores, pois são implementadas através de simples deslocamentos de sinais e somas. Assim multiplicar por 10 corresponde a multiplicar por 2 somar com a multiplicação por 8.
 
{{fig|4.10|Código RTL do multiplicador por 10| RTL_multiplicador10.png| 300 px |}}
 
O tipo INTEGER não é muito adequado para realizar as operações aritméticas por três motivos:
# Com INTEGER as operações só podem ser feita com no máximo 32 bits.
# Se não for dado um RANGE, as operações serão feitas com 32 bits, gerando hardware desnecessário
# Alguns simuladores (como o ModelSim) ao incrementarem um INTEGER além do valor máximo interrompem a simulação por overflow.
{{collapse top | tb_somador_int.do}}
<syntaxhighlight lang=tcl>
# Define o nome do componente VHDL
set arq_vhd somador_int
 
vlib rtl_work
vmap work rtl_work
vcom -93 -work work "../../${arq_vhd}.vhd"
vsim work.${arq_vhd}(ifsc)
 
# Adiciona sinais ao waveform
add wave -position end sim:/$arq_vhd/a
add wave -position end sim:/$arq_vhd/b
add wave -position end sim:/$arq_vhd/s
 
#Adiciona sinais ao waveform e mostra o valor em UNSIGNED
add wave -position end -radix unsigned sim:/$arq_vhd/a
add wave -position end -radix unsigned sim:/$arq_vhd/b
add wave -position end -radix unsigned sim:/$arq_vhd/s
 
# Força valores em b e varia a de 0 a 15
 
force -freeze sim:/$arq_vhd/b 7 0
for {set i 0} {$i < 16} {incr i} {
    force -freeze sim:/$arq_vhd/a 10#$i 0
    run 1 ns
}
 
 
# Ajustes visuais
configure wave -timelineunits ns
wave zoom full
</syntaxhighlight>
 
{{collapse bottom}}
{{fig|4.11|Simulação com parada devido a erro de overflow no ModelSim | OverflowModelSim_somador_int.png| 800 px |}}
Note que nessa simulação, ao atingir a soma 9 + 7 = 16, ocorre o overflow e o simulador indica o '''Fatal error''' e para.
** Fatal: (vsim-3421) Value '''16 is out of range 0 to 15.'''
 
{{fig|4.12|Erro Fatal no ModelSim | OverflowModelSim.png| 800 px |}}


Veja como ficaria um somador usando o tipo UNSIGNED como portas de entrada e saída.
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
entity mux4x1 is
library ieee;
port
use ieee.numeric_std.all;
(
 
-- Input ports
entity somador is
X: in bit_vector (3 downto 0);
generic (N : natural := 4);
                Sel : in bit_vector (1 downto 0);
port (  
-- Output ports
a, b : in unsigned(N-1 downto 0);
Y : out bit
s : out unsigned(4 downto 0)
);
);
end entity;
end entity;


-- Implementação com lógica pura
architecture ifsc of somador is
architecture v_logica_pura of mux4x1 is
s <=  a + b;
end architecture;
</syntaxhighlight>
 
Mesmo essa solução acima não é a mais adequada, pois utiliza portas que não estão de acordo com a recomendação do padrão industrial e que é compatível com as ferramentas de EDA no mercado. O ideal é ter sempre as portas definidas com tipos std_logic ou std_logic_vector. Por isso a recomendação é adotar uma solução como a seguinte:
 
<syntaxhighlight lang=vhdl>
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity somador_slv is
generic (N : natural := 4);
port (
a, b : in std_logic_vector(N-1 downto 0);
s : out std_logic(4 downto 0);
);
end entity;
 
architecture ifsc_v1 of somador_slv is
begin
s <=  std_logic_vector(unsigned(a) + unsigned(b));
end architecture;


architecture ifsc_v2 of somador_slv is
signal a_uns, b_uns : unsigned(N-1 downto 0);
signal s_uns : unsigned(N-1 downto 0);
begin
begin
Y <= (X(0) and (not Sel(1)) and (not Sel(0))) or
s <= std_logic_vector(s_uns)
      ...
s_uns <= a_uns + b_uns;
a_uns <=  unsigned(a);
a_uns <=  unsigned(b);
end architecture;
end architecture;
</syntaxhighlight>
</syntaxhighlight>


No entanto, o MUX4:1 também pode ser descrito utilizando a instrução '''WHEN-ELSE'''
{{fig|4.12|Simulação correta no ModelSim | SomadorModelSim.png| 800 px |}}
Note que nessa simulação, ao atingir a soma 9 + 7 = 16, ocorre o overflow, como são apenas 4 bits que são utilizados, o resultado 10000 é guardado como 0000 e  e o simulador indica corretamente o s = 0 no instante 9ns.
 
Para utilizar corretamente os tipos UNSIGNED e SIGNED leia atentamente
*A biblioteca [[Numeric std.vhd]] define os tipos UNSIGNED e SIGNED.
 
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
<optional_label>: <target> <=
package NUMERIC_STD is
<value> when <condition> else
  type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
<value> when <condition> else
  type SIGNED is array (NATURAL range <>) of STD_LOGIC;
...
<value> else
<value>;
</syntaxhighlight>
</syntaxhighlight>


*Importante: O '''último ELSE''' sem condição para cobrir todos os demais valores para evitar a criação de LATCHES.
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 UNSIGNEDAlém disso também define algumas funções muito utilizadas como:
  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]'''
<syntaxhighlight lang=vhdl>
  --============================================================================
  --  RESIZE Functions
  --============================================================================
  function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
  function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;


No caso do MUX4:1 ele poderia ser descrito como: 
  --============================================================================
<syntaxhighlight lang=vhdl>
  -- Conversion Functions
-- Implementação com WHEN ELSE
  --============================================================================
architecture v_WHEN_ELSE of mux4x1 is
  function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
begin
  function TO_INTEGER (ARG: SIGNED) return INTEGER;
Y <= X(0) when Sel = "00" else
  function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
      X(1) when Sel = "01" else
  function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
      X(2) when Sel = "10" else
      X(3);
end architecture;
</syntaxhighlight>
</syntaxhighlight>
:Ver pag. 73 a 78 de <ref name="PEDRONI2010b"> PEDRONI, V. A. '''Circuit design and simulation with VHDL'''. 2nd. ed. New Delhi: PHI Learning Private, 2015.</ref>


Outra forma de descrever o MUX4:1 seria utilizando a instrução '''WITH-SELECT'''
[[Arquivo:SumaryOfNumeric_std.gif]]


<syntaxhighlight lang=vhdl>
[[Arquivo:Numeric_stdConvertions.gif]]
<optional_label>: with <expression> select
<target> <=
<value> when <choices>,
<value> when <choices>,
...
<value> when others;
</syntaxhighlight>


*Importante: Para cobrir todas as demais possibilidades deve ser utilizado o '''WHEN OTHERS''' evitando novamente a criação de LATCHES, ou erros de análise.
FONTE: http://www.doulos.com/knowhow/vhdl_designers_guide/numeric_std/


Error (10313): VHDL Case Statement error ...: Case Statement choices must cover all possible values of expression
<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>


* 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'''.
;Nivelamento 5 - Instruções WHEN_ELSE, WITH_SELECT, CONFIGURATION:


<syntaxhighlight lang=vhdl>
Para ilustrar essas instruções utilizaremos o exemplo de um Mux4x1.  Um multiplexador digital de N entradas e 1 saída, frequentemente abreviado como MUX N:1, é um circuito digital muito utilizado para rotear sinais digitais. Ele desempenha a função de selecionar uma das entradas para ser encaminhada para a saída com base em um sinal de seleção (ou controle).
-- Implementação com WITH SELECT
architecture v_WITH_SELECT of mux4x1 is


begin
{{collapse top | Mux2x1}}
with Sel select
A tabela verdade que descreve um MUX2:1 é mostrada abaixo:
Y <= X(0) when "00",    -- note o uso da ,
<center>
      X(1) when "01",
{| class="wikitable" style="text-align:center;"
      X(2) when "10",
|- style="font-weight:bold;"
      X(3) when others; -- note o uso de others, para todos os demais valores. 
! X1
                        -- Não pode ser substituido por "11" mesmo que o signal seja bit_vector.
! X0
end architecture;
! Sel
</syntaxhighlight>
! style="background-color:#c0c0c0;" | Y
 
|-
* Note que para associar uma entre várias arquiteturas com a sua ENTITY pode-se utilizar a instrução CONFIGURATION. No exemplo abaixo a ARCHITECTURE que está descomentada é a que será associada a ENTITY mux4x1. 
| 0
* Caso não se use a instrução CONFIGURATION, a última ARCHITECTURE será associada a ENTITY. 
| 0
* Apesar de apenas uma das ARCHITECTUREs ser associada, todas elas devem estar sintaticamente corretas, pois passarão pelo processo de ANÁLISE E SINTESE.
| 0
<syntaxhighlight lang=vhdl>
| style="background-color:#c0c0c0;" | 0
CONFIGURATION <configuration_name> OF <entity_name> IS
|-
FOR <architecture_name> END FOR;
| 0
END CONFIGURATION;
| 0
</syntaxhighlight>
| 1
 
| style="background-color:#c0c0c0;" | 0
<syntaxhighlight lang=vhdl>
|-
-- Design Unit que associa a architecture com a entity
| 0
CONFIGURATION cfg_ifsc OF mux4x1 IS
| 1
FOR v_logica_pura END FOR;
| 0
-- FOR v_WHEN_ELSE END FOR;
| style="background-color:#c0c0c0;" | 1
-- FOR v_WITH_SELECT END FOR;
|-
END CONFIGURATION;
| 0
</syntaxhighlight>
| 1
 
| 1
* Faça a análise e sintese do mux4x1, associando a architecture v_logica_pura, depois v_WITH_SELECT, depois v_WHEN e por último v_IF_ELSE. 
| style="background-color:#c0c0c0;" | 0
* Note a diferença entre os RTL Viewer obtidos para cada architecture.
|-
{{fig|2.1|Código RTL do mux4x1 v_logica_pura| RTL_mux4x1v1.png| 300 px |}}
| 1
{{fig|2.2|Código RTL do mux4x1 v_WHEN_ELSE| RTL_mux4x1v2.png| 400 px |}}
| 0
{{fig|2.3|Código RTL do mux4x1 v_WITH_SELECT| RTL_mux4x1v3.png| 200 px |}}
| 0
:'''OBS''': [https://en.wikipedia.org/wiki/Register-transfer_level Register Transfer-Level] (RTL) é uma abstração na qual o circuito é descrito em termos de fluxo de sinais entre os registradores presentes no hardware e as operações combinacionais realizadas com esses dados.
| style="background-color:#c0c0c0;" | 0
 
|-
;PARA O PRÓXIMO ENCONTRO:
| 1
*Realize a simulação das 3 arquiteturas do MUX4:1 no Modelsim
| 0
*Crie um arquivo tb_mux4x1_v1.do que repita a simulação da arquitetura v1
| 1
*Crie um arquivo tb_mux4x1_v2.do que repita a simulação da arquitetura v2
| style="background-color:#c0c0c0;" | 1
*Crie um arquivo tb_mux4x1_v3.do que repita a simulação da arquitetura v1
|-
*Inclua todos os arquivos .do no projeto do Quartus e salve o arquivo QAR
| 1
*Ver essa página [[Simulação Funcional usando o ModelSim]]
| 1
{{collapse bottom}}
| 0
| style="background-color:#c0c0c0;" | 1
|-
| 1
| 1
| 1
| style="background-color:#c0c0c0;" | 1
|}
</center>


===Unidade 2 - Dispositivos Lógicos Programáveis ===
O MUX2:1 também pode ser representado de forma resumida por:
* 3 ENCONTROS
<center>
{{collapse top | Unidade 2 - Dispositivos Lógicos Programáveis}}
{| class="wikitable" style="text-align:center;"
 
|- style="font-weight:bold;"
;Encontro 5 (1 mar):
! X1
*Introdução aos dispositivos lógicos programáveis:
! X0
:* Conceito, tipos de PLDs
! Sel
:* SPLD:
! style="background-color:#c0c0c0;" | Y
::*PAL (e.g. [[Media: PAL16.pdf| PAL16 da Texas Instruments (1984)]])
|-
::*PLA (e.g. [[Media: PLS100.pdf| PLS100 da Philips Semiconductors (1993)]])
| -
::*GAL (e.g. [[Media: GAL16V8.pdf| GAL16V8 da Lattice (2004)]])
| X0
:* CPLDs (e.g. [[Media: ATF2500C.pdf| ATF2500C da Atmel (2008)]], [https://br.mouser.com/c/ds/semiconductors/programmable-logic-ics/cpld-complex-programmable-logic-devices/ Complex Programmable Logic Devices Datasheets - Mouser])  
| 0
| style="background-color:#c0c0c0;" | X0
|-
| X1
| -
| 1
| style="background-color:#c0c0c0;" | X1
|}
</center>
Onde o X0 e X1 na entrada podem assumir os valores 0 ou 1, e o simbolo "-" corresponde ao ''don't care'' (em VDHL)


{{collapse top | expand=true| Exemplos de PLDs}}
A função booleana que descreve a operação de um MUX 2:1 pode ser representada da seguinte forma:
{{fig|2.1|Exemplo de PAL| PedroniFig4_4a.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}


{{fig|2.2|Exemplo de PLA| PedroniFig4_4b.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}


{{fig|2.3|Macrobloco do PLD EP300 da ALTERA| ep310_macrocell.jpg| 400 px | https://www.altera.com/solutions/technology/system-design/articles/_2013/in-the-beginning.html}}
<math>  Y =  \overline{Sel} . X0 + Sel . X1 </math>


{{fig|2.4|Macrocélula dos PLDs Clássicos EP600, EP900, EP1800 da ALTERA (1999)| Macrocell_EP900.png| 400 px | https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ds/archives/classic.pdf}}
Onde Y é a saída; Sel é o sinal de seleção; X0 e X1 são as entradas.
 
{{fig|2.5|Architetura do PLD EP1800 da ALTERA| ep1800_block_diagram.jpg| 400 px | https://www.altera.com/solutions/technology/system-design/articles/_2013/in-the-beginning.html}}
 
{{fig|2.6|Architetura do PLD EP1800 da ALTERA| ep1800_block_diagram2.jpg| 400 px | https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ds/archives/classic.pdf}}
 
{{fig|2.7|Pinagem e tipos de encapsulamento do PLD EP1800 da ALTERA| PackagePinOut_EP1810.png| 400 px | https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ds/archives/classic.pdf }}
 
{{fig|2.8|Architetura do CPLD MAX 5000 da ALTERA| max_5000_architecture.jpg| 400 px | https://www.altera.com/solutions/technology/system-design/articles/_2013/in-the-beginning.html}}
{{collapse bottom}}
{{collapse bottom}}


* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 1 e 2
{{collapse top | expand=false |Mux4x1}}
O MUX4:1 pode ser representado de forma resumida pela tabela verdade:


;PARA O PRÓXIMO ENCONTRO:
<center>
*[https://www.intel.com/content/www/us/en/programmable/customertraining/webex/PLDBasics_History/presentation_html5.html History of Programmable Logic] Intel
{| class="wikitable" style="text-align:center;"
*[https://www.intel.com/content/www/us/en/products/details/fpga/platforms.html See why Microsoft chose Intel FPGAs to accelerate their next generation cloud infrastructure]
|- style="font-weight:bold;"
*[https://www.youtube.com/watch?v=ecyyZ6zTLic Microsoft's Bing* Intelligent Search with Intel® FPGAs]
! colspan="4" | Entradas
*Seção 4.1 a 4.5 de [http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf Review of Field Programmable Gate Arrays (FPGAs)], Volnei A. Pedroni. (ou para quem preferir em português, leia as seções 18.1 a 18.3 do livro: PEDRONI, Volnei A '''Eletrônica Digital Moderna e VHDL: Princípios Digitais, Eletrônica Digital, Projeto Digital, Microeletrônica e VHDL'''; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. ISBN 9788535234657. Têm 16 exemplares na [http://biblioteca.ifsc.edu.br/index.asp?codigo_sophia=30631 biblioteca do Campus]. Número de chamada: 621.392 P372e)
! colspan="2" | Seleção
*Seção 2.1 Dispositivos lógicos programáveis do TCC [[Integração de ramais analógicos com FPGA utilizando processador softcore]], Renan Rodolfo da Silva.
! Saída
 
|- style="font-weight:bold;"
;Encontro 6 (5 mar):
| X3
* Arquitetura de FPGAs (Xilinx e Altera): CLB, LAB, LUT, Flip_flop D, RAM, DSP, Clock, PLL, DLL, I/O
| X2
:FONTE: [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA
| X1
 
| X0
{{collapse top | expand=true |Exemplos de FPGA}}
| Sel1
 
| Sel0
{{fig|2.9|Arquitetura de um FPGA | Architecture_FPGAs.png| 600 px | https://www.intel.com/content/www/us/en/docs/programmable/683176/18-1/fpga-overview-opencl-standard.html}}
| style="background-color:#c0c0c0;" | Y
 
|-
{{fig|2.10|Diagrama simplificado da ALM de um FPGA Intel/Altera | ALM_LUT_FPGAs.png| 600 px | https://www.intel.com/content/www/us/en/content-details/771003/fpga-architecture-8-input-lut-legacy-white-paper.html}}
| -
 
| -
{{fig|2.11|Arquitetura interna de uma LUT | LUT_FPGAs.png| 800 px | [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA}}
| -
 
| X0
{{fig|2.12|Configuração de uma LUT | LUT_FPGAs_Config.png| 1000 px | https://www.allaboutcircuits.com/technical-articles/purpose-and-internal-functionality-of-fpga-look-up-tables/}}
| 0
 
| 0
{{fig|2.13|Arquitetura do Cyclone® V Intel/Altera | CycloneV_FPGAs.jpg| 600 px | https://www.intel.com.br/content/www/br/pt/products/details/fpga/cyclone/v/article.html}}
| style="background-color:#c0c0c0;" | X0
 
|-
{{fig|2.14|Leiaute de um FPGA Xilinx genérico | Leiaute2_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }}
| -
 
| -
{{fig|2.15|Roteamento de sinal em um FPGA | Roteamento_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }}
| X1
 
| -
{{fig|2.16|Tecnologias usadas na configuração de FPGAs| FPGA_programming.png| 800 px | https://www.sciencedirect.com/topics/computer-science/one-time-programmable }}
| 0
{{collapse bottom}}
| 1
 
| style="background-color:#c0c0c0;" | X1
:Ver também [https://www.youtube.com/watch?v=kU2SsUUsftA&t=2s SRAM], [https://www.youtube.com/watch?v=7qa1dsCpMMo EEPROM], [https://www.youtube.com/watch?v=ELl3abwYQ90&list=PL9B4edd-p2agcmJl2EscTdLudLv58uXHt&index=1 What Is Flash Memory]
|-
 
| -
* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 3 e 4
| X2
 
| -
;PARA O PRÓXIMO ENCONTRO:
| -
* Leia a assista a alguns dos vídeos sobre a historia e processo de produção dos chips.
| 1
:*[https://www.semiwiki.com/forum/content/1535-brief-history-fabless-semiconductor-industry.html A Brief History of the Fabless Semiconductor Industry]
| 0
:*[http://www.semiwiki.com/forum/content/1539-brief-history-tsmc.html Taiwan Semiconductor Manufacturing Corporation (TSMC)], [http://www.globalfoundries.com/ GLOBALFOUNDRIES]
| style="background-color:#c0c0c0;" | X2
:*[https://www.linkedin.com/pulse/free-copy-fabless-transformation-semiconductor-industry-daniel-nenni-1 Fabless: The Transformation of the Semiconductor Industry, 2014] - Download free
|-
:*[https://www.youtube.com/watch?v=W3rfVpkNquA Produção do FinFET], [https://www.youtube.com/watch?v=d9SWNLZvA8g]
| X3
:*[https://en.wikipedia.org/wiki/3_nm_process 3 nm process], [https://en.wikipedia.org/wiki/Multigate_device multi-gate MOSFET]
| -
:*[https://www.youtube.com/watch?v=UvluuAIiA50 GLOBALFOUNDRIES Sand to Silicon], [https://www.youtube.com/watch?v=F2KcZGwntgg How Microchips are made] - Processo de fabricação de um chip
| -
:*[https://en.wikipedia.org/wiki/Foundry_model Foundries], [https://en.wikipedia.org/wiki/List_of_semiconductor_fabrication_plants List of semiconductor fabrication plants]
| -
:*[https://www.youtube.com/watch?v=GU87SH5e0eI A dependência do mundo com a TMSC]
| 1
| 1
| style="background-color:#c0c0c0;" | X3
|}
</center>
A função booleana que descreve a operação de um MUX 4:1 pode ser representada da seguinte forma:


;Encontro 7 (8 mar):
<math> Y = X0 . \overline{Sel1} . \overline{Sel0} + X1 . \overline{Sel1} . Sel0 +  X2 . Sel1 . \overline{Sel0} + X3 . Sel1 . Sel0  </math>
* System on Chip
{{collapse bottom}}
{{fig|2.17|Altera - Visão geral do dispositivo Arria V SX e ST| ArriaV_SX_ST_Chip.png| 800 px | https://br.mouser.com/datasheet/2/612/av_51001-1623623.pdf}}


{{fig|2.18|Altera - Agilex 7 SoCs HPS Digrama de Blocos| Agilex7SoC_Blocos.png| 800 px | https://static6.arrow.com/aropdfconversion/b568cfe009abfed6a28eff56700189883d7fc179/ag-overview-683458-666707.pdf}}
Dada a função booleana do MUX4:1 é simples para descreve-lo em VHDL utilizando apenas operadores lógicos.


* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 1 a 4
<syntaxhighlight lang=vhdl>
;PARA O PRÓXIMO ENCONTRO:
entity mux4x1 is
:* Ver preços de DLPs em
port
::*[https://www.arrow.com/ ARROW]
(
::*[https://www.digikey.com/ Digikey]
-- Input ports
::*[https://mouser.com Mouser Electronics]
X: in bit_vector (3 downto 0);
::*[https://www.newark.com/ Newark]
                Sel : in bit_vector (1 downto 0);
:* Fabricantes de DLPs/FPGAs e familias de DLPs atuais.
-- Output ports
::*[https://www.altera.com/products/fpga/overview.html ALTERA/INTEL] - Stratix, Arria, Cyclone, Max, Agilex
Y : out bit
::*[https://www.xilinx.com/products/silicon-devices/fpga.html Xilinx/AMD] - Virtex, Kintex, Artix, Zynq (SoC)
);
::*[https://www.microchip.com/en-us/products/fpgas-and-plds/fpgas Microchip] - Igloo, PolarFire
end entity;
::*[http://www.latticesemi.com/Products.aspx#_D5A173024E414501B36997F26E842A31 Lattice]  - ECP, iCE, Mach


{{collapse bottom}}
-- Implementação com lógica pura
architecture v_logica_pura of mux4x1 is


===Unidade 3 - Circuitos sequenciais (Implementação com HDL) ===
begin
* 8 ENCONTROS
Y <= (X(0) and (not Sel(1)) and (not Sel(0))) or
{{collapse top | expand=true | Unidade 3 - Circuitos sequenciais (Implementação com HDL)}}
      ...
;Encontro 8 (12 mar):
end architecture;
*Flip-Flop e circuitos sequenciais.
:*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>
</syntaxhighlight>
:*Instrução '''IF'''
 
No entanto, o MUX4:1 também pode ser descrito utilizando a instrução '''WHEN-ELSE'''
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
[rótulo:] IF condição THEN
<optional_label>: <target> <=
            afirmação_sequencial;
<value> when <condition> else
            afirmação_sequencial;
<value> when <condition> else
            ...
...
        ELSIF condição THEN
<value> else
            afirmação_sequencial;
<value>;
            afirmação_sequencial;
</syntaxhighlight>
            ...
 
        ELSE
*Importante: O '''último ELSE''' sem condição para cobrir todos os demais valores para evitar a criação de LATCHES.
            afirmação_sequencial;
Warning (13012): Latch ... has unsafe behavior
            afirmação_sequencial;
            ...
        END IF [rótulo];


</syntaxhighlight>
* No QuartusII existe um template pronto para ser utilizado em: '''[Edit > Insert Template > Language templates = VHDL (+) > Constructs (+) > Concurrent Statemens (+) > Conditional Signal Assignment]'''
:*Exemplos:
 
::* DFFs com Reset Assincrono e Reset Sincrono, com Enable, com Preset (Variação Ex 6.1).
No caso do MUX4:1 ele poderia ser descrito como:   
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
--Flip Flop tipo D com reset assincrono, sensivel a borda de subida.
-- Implementação com WHEN ELSE
process (clock,reset)
architecture v_WHEN_ELSE of mux4x1 is
begin
begin
  if (reset = '1') then
Y <= X(0) when Sel = "00" else
       q <= '0';
       X(1) when Sel = "01" else
-- elsif (clock'event and clock = '1') then or
      X(2) when Sel = "10" else
  elsif (rising_edge(clock)) then
       X(3);
       q <= d;
end architecture;
  end if;
end process;
</syntaxhighlight>
</syntaxhighlight>
{{fig|5.1|RTL de Flip-flop D de borda de subida, com reset assíncrono| FF_D_RST.png| 400 px | }}
 
Outra forma de descrever o MUX4:1 seria utilizando a instrução '''WITH-SELECT'''
 
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
--Flip Flop tipo D com preset assincrono e sinal de enable, sensivel a borda de descida.
<optional_label>: with <expression> select
process (clock, preset)
<target> <=  
begin
<value> when <choices>,
  if (preset = '1') then
<value> when <choices>,
      q <= '1';
...
  elsif (falling_edge(clock)) then
<value> when others;
      if (enable = '1') then
        q <= d;
      end if;
  end if;
end process;
</syntaxhighlight>
</syntaxhighlight>
{{fig|5.2|RTL de Flip-flop D de borda de descida, com preset assíncrono e enable| FF_D_PRST.png| 400 px | }}


;Encontro 9 (15 mar):
*Importante: Para cobrir todas as demais possibilidades deve ser utilizado o '''WHEN OTHERS''' evitando novamente a criação de LATCHES, ou erros de análise.
::* Comparar com Latch (sem clk'event).
 
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'''.
 
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
--Latch tipo D com reset assincrono.
-- Implementação com WITH SELECT
process (enable, reset, d)
architecture v_WITH_SELECT of mux4x1 is
 
begin
begin
  if (reset = '1') then
with Sel select
      q <= '0';
Y <= X(0) when "00",    -- note o uso da ,
  elsif (enable='1')) then
      X(1) when "01",
       q <= d;
      X(2) when "10",
  end if;
       X(3) when others; -- note o uso de others, para todos os demais valores. 
end process;
                        -- Não pode ser substituido por "11" mesmo que o signal seja bit_vector.
end architecture;
</syntaxhighlight>
</syntaxhighlight>
{{fig|5.3|RTL de Latch D de com reset assíncrono e enable ativo alto| LATCH_D_RST.png| 400 px | }}
* Na figura abaixo, note que o Latch é implementado utilizando a LUT do elemento lógico do FPGA, enquanto que o Flip-flop utiliza o componente já disponível neste elemento lógico.
*[[Evite os latches no projeto]]


{{fig|5.4|Comparação do ''Technology Map'' de um Latch_D (esquerda) com FF_D (direita)| FF_D_LATCH_D.png| 800 px | }}
* Note que para associar uma entre várias arquiteturas com a sua ENTITY pode-se utilizar a instrução CONFIGURATION. No exemplo abaixo a ARCHITECTURE que está descomentada é a que será associada a ENTITY mux4x1. 
* Caso não se use a instrução CONFIGURATION, a última ARCHITECTURE será associada a ENTITY. 
* Apesar de apenas uma das ARCHITECTUREs ser associada, todas elas devem estar sintaticamente corretas, pois passarão pelo processo de ANÁLISE E SINTESE.
<syntaxhighlight lang=vhdl>
CONFIGURATION <configuration_name> OF <entity_name> IS
FOR <architecture_name> END FOR;
END CONFIGURATION;
</syntaxhighlight>


:*Ver pag. 151 a 156 de <ref name="PEDRONI2010b"/>
:*[[Especificando o valor de Power-Up do flip-flop D]]
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
-- Flip Flop tipo D com reset síncrono sensível a borda de subida.
-- Design Unit que associa a architecture com a entity
-- Modifique a descrição para que o reset_ass seja assíncrono e reset_sinc seja síncrono.
CONFIGURATION cfg_ifsc OF mux4x1 IS
-- Note que a função rising_edge(clock) é equivalente a (clock'event and clock'last_value = '0' and clock = '1'))
FOR v_logica_pura END FOR;
 
-- FOR v_WHEN_ELSE END FOR;
process (clock, reset)
-- FOR v_WITH_SELECT END FOR;
begin
END CONFIGURATION;
  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>
</syntaxhighlight>
{{fig|5.5|RTL do Flip-flop D com reset assíncrono e reset síncrono| FF_D_RST_SINC_ASINC.png| 400 px | }}
*[[Como evitar o uso da lógica combinacional no reset síncrono]]


*Exercício: Implemente um registrador com N FF_D no lugar de um único FF_D.  
* Faça a análise e sintese do mux4x1, associando a architecture v_logica_pura, depois v_WITH_SELECT, depois v_WHEN e por último v_IF_ELSE.  
{{fig|5.6|RTL do Registrador (de 4 bits) com reset assíncrono| REG_RST.png| 400 px | }}
* Note a diferença entre os RTL Viewer obtidos para cada architecture.
{{fig|5.7|Techonogy Map do Registrador (de 4 bits) com reset assíncrono| TM_REG_RST.png| 400 px | }}
{{fig|2.1|Código RTL do mux4x1 v_logica_pura| RTL_mux4x1v1.png| 300 px |}}
* Faça a simulação funcional do DFFs e do Latch
{{fig|2.2|Código RTL do mux4x1 v_WHEN_ELSE| RTL_mux4x1v2.png| 400 px |}}
{{fig|2.3|Código RTL do mux4x1 v_WITH_SELECT| RTL_mux4x1v3.png| 200 px |}}
:'''OBS''': [https://en.wikipedia.org/wiki/Register-transfer_level Register Transfer-Level] (RTL) é uma abstração na qual o circuito é descrito em termos de fluxo de sinais entre os registradores presentes no hardware e as operações combinacionais realizadas com esses dados.


;Encontro 10 (22 mar):
;RESUMO:
*Implementar um registrador com N FF_D usando a instrução '''FOR GENERATE'''.
*[https://wiki.sj.ifsc.edu.br/images/5/5c/3-concorrente.pdf Slides Declarações Concorrentes]


<syntaxhighlight lang=vhdl>
;PARA O PRÓXIMO ENCONTRO:
-- Instrução concorrente FOR GENERATE.
*Realize a simulação das 3 arquiteturas do MUX4:1 no Modelsim
-- Note que neste caso o '''label''' é obrigatório
*Crie um arquivo tb_mux4x1_v1.do que repita a simulação da arquitetura v1
*Crie um arquivo tb_mux4x1_v2.do que repita a simulação da arquitetura v2
*Crie um arquivo tb_mux4x1_v3.do que repita a simulação da arquitetura v1
*Inclua todos os arquivos .do no projeto do Quartus e salve o arquivo QAR
*Ver essa página [[Simulação Funcional usando o ModelSim]]
-->
{{collapse bottom}}
 
===Unidade 2 - Dispositivos Lógicos Programáveis ===
 
* 5 ENCONTROS
{{collapse top | expand=true | Unidade 2 - Dispositivos Lógicos Programáveis}}
<!--
;Encontro 2 (20 mar.):


label: FOR identificador IN faixa GENERATE
*[https://drive.google.com/file/d/1VNUqU3nBkNWv3w-yT3HT18eY878JcgXz/view?usp=drive_link Introdução a linguagem de descrição de hardware (DHL)]
  [Parte_Declarativa
BEGIN]
  Instruções_concorrentes
  ...
END GENERATE [label];
</syntaxhighlight>


*Implementar um registrador de deslocamento de N bits.
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
entity shift_reg is
-- Exemplo: Declaração do circuito combinacional
generic ( N : natural := 4);
-- Y = A'.B + A.B'
port (
-- Autor:     prof. Marcos Moecke
clock, reset : in std_LOGIC ;
-- Data:     20/03/2025
d_in:  in std_LOGIC;
-- Filename:  REV1.vhd
q_out : out std_LOGIC);
-- A declaracao abaixo nao e necessaria pois o pacote standart da biblioteca std e autodeclarada (por default)
library std;
use std.standard.all;
 
--
entity REV1 is
    port (a, B: in bit; y: out bit);
end entity;
end entity;


architecture ifsc_v1 of shift_reg is
-- Implementacao direta com funcoes logicas
signal d: std_logic_vector(N-1 downto 0);
architecture ifsc_v1 of rev1 is
signal q: std_logic_vector(N-1 downto 0);
begin
begin
  ...
    Y <= (not a and b) or (A and not B);
end architecture;
end architecture;
</syntaxhighlight>
{{fig|5.8|Technology Map de Shift Register| shift_reg_TM.png| 800 px | }}
{{fig|5.9|Simulação de Shift Register| shift_reg_SIM.png| 800 px | }}


*Implementar um contador crescente 0-N (baseado no Ex.6.2), com N = 2^Mbits-1 (1 3 7 15)
-- Implementacao com funcoes logica por etapas
:*Com overflow no valor máximo
architecture ifsc_v2 of rev1 is
<syntaxhighlight lang=vhdl>
signal nota, notb : bit;    -- sinais internos podem ser declarados em uma unica linha se forem do mesmo tipo
entity conta_0_N is
signal and_1 : bit;          -- o nome dos sinais nao pode usar palavras reservadas do VHDL como and.
generic (MAX : natural := 15);
signal and_2 : bit;          -- usar uma linha para cada sinal pode ser uma boa pratica de documentacao
port (clock, reset: in  std_logic; q : out integer range 0  to MAX);
signal or_3 : bit;
end entity;
begin
notA <= not A;
notb <= not B;
and_1 <= nota and b;
and_2 <= (A and notB);
or_3 <= and_1 or and_2;
Y <= or_3;                 -- assim se faz a conexao entre um sinal interno uma saida
-- as ultimas 2 linhas acima poderiam ser tambem simplificadas
-- Y <= and_1 or and_2;
end architecture;


architecture ifsc_v1 of conta_0_N is
-- Implementacao com WHEN-ELSE
architecture ifsc_v3 of rev1 is
begin
 
end architecture;
 
-- Implementacao com WITH-SELECT
architecture ifsc_v4 of rev1 is
begin


begin
process (clock,reset)
variable count : integer range 0  to MAX;
begin
if (reset = '1') then
count := 0;
elsif (rising_edge(clock)) then
count := count + 1;
end if;
q <= count;
end process;
end architecture;
end architecture;
-- associacao da architetura a entidade.
-- Se nao for feita, a ultima arquitetura e associada
configuration rev1_cfg of REV1 is
-- for ifsc_v1 end for;
for ifsc_v2 end for;
-- for ifsc_v3 end for;
-- for ifsc_v4 end for;
end configuration;
</syntaxhighlight>
</syntaxhighlight>
{{fig|5.10|RTL de contador crescente| Counter_0_M_RTL.png| 600 px | }}


;Encontro 11 (26 mar):
;PARA O PRÓXIMO ENCONTRO:
*Implementar um contador crescente 0 até N, com N ≠ 2^Mbits (5, 10)
* Alunos que fizeram ELD129002 : reveja [[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]]
:*Com overflow no valor máximo
* Alunos que não fizeram ELD129002 : siga o procedimento [[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]].
{{fig|5.11|RTL contador crescente 0 a 5| Counter_0_5_RTL.png| 600 px | }}
* Se tiver dúvidas pergunte no chat da turma, que o professor ou algum colega pode ajudá-lo
{{fig|5.12|Simulação do contador crescente 0 a 5| Counter_0_5_SIM.png| 800 px | }}
:*Com parada no valor máximo


*Implementar um contador decrescente N até 0, com N ≠ 2^Mbits (5, 10)
* Implente e teste as várias versões de '''architecture''' da '''entity REV1''' .
:*Com underflow no valor mínimo
:1) diretamente com as funções lógicas
{{fig|5.13|Simulação do contador decrescente 5 a 0| Counter_5_0_SIM.png| 800 px | }}
:2) com funções lógicas por etapas
:3) com WHEN-ELSE
:4) com WITH-SELECT


:*Com parada no valor mínimo
{{fig|5.14|Simulação do contador decrescente 5 a 0 com parada| Counter_5_0_SIM_stop.png| 800 px | }}


;Encontro 3 (25 mar.):
*Introdução aos dispositivos lógicos programáveis:
:* Conceito, tipos de PLDs
:* SPLD:
::*PAL (e.g. [https://wiki.sj.ifsc.edu.br/images/8/86/PAL16.pdf#page=5| PAL16 da Texas Instruments (1984)])
::*PLA (e.g. [https://wiki.sj.ifsc.edu.br/images/5/57/PLS100.pdf#page=2| PLS100 da Philips Semiconductors (1993)])
::*GAL (e.g. [https://wiki.sj.ifsc.edu.br/images/5/5d/GAL16V8.pdf#page=6| GAL16V8 da Lattice (2004)])
:* CPLDs (e.g. [https://wiki.sj.ifsc.edu.br/images/c/c8/ATF2500C.pdf#page=9| ATF2500C da Atmel (2008)], [https://br.mouser.com/c/ds/semiconductors/programmable-logic-ics/cpld-complex-programmable-logic-devices/ Complex Programmable Logic Devices Datasheets - Mouser])


;DESAFIO: Implementar um contador bidirecional entre MIN e MAX.  Uma entrada DIR indica a direção da contagem. Considere DIR = 0 (crescente) e  DIR = 1 (decrescente).
{{collapse top | expand=true| Exemplos de PLDs}}
:*'''Versão 1:''' Com underflow no valor mínimo (MIN) e overflow no máximo (MAX).
{{fig|2.1|Exemplo de PAL| PedroniFig4_4a.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}
:*'''Versão 2:''' Com parada no valor mínimo (MIN), se decrescente e também no máximo (MAX) se crescente.


[[Restringir a frequencia máxima de clock no Quartus II]]
{{fig|2.2|Exemplo de PLA| PedroniFig4_4b.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}


{{fig|2.3|Macrobloco do PLD EP300 da ALTERA| ep310_macrocell.jpg| 400 px | https://www.altera.com/solutions/technology/system-design/articles/_2013/in-the-beginning.html}}


;Encontro 12 (2 abr.):
{{fig|2.4|Macrocélula dos PLDs Clássicos EP600, EP900, EP1800 da ALTERA (1999)| Macrocell_EP900.png| 400 px | https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ds/archives/classic.pdf}}
Instruções do tipo '''LOOP''': LOOP incondicional, '''FOR-LOOP''', '''WHILE-LOOP''', '''NEXT''', '''EXIT'''


*Instrução '''LOOP''' incondicional:
{{fig|2.5| Princípio de construção de uma LUT| LUT_pedroni.png | 400 px | https://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}
<syntaxhighlight lang=vhdl>
 
[rótulo:] LOOP
{{fig|2.6|Architetura do PLD EP1800 da ALTERA| ep1800_block_diagram.jpg| 400 px | https://www.altera.com/solutions/technology/system-design/articles/_2013/in-the-beginning.html}}
            afirmação_sequencial;
            afirmação_sequencial;
            ...
          END LOOP [rótulo];
</syntaxhighlight>


*Instrução '''FOR-LOOP''':
{{fig|2.7|Architetura do PLD EP1800 da ALTERA| ep1800_block_diagram2.jpg| 400 px | https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ds/archives/classic.pdf}}
<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''':
{{fig|2.8|Pinagem e tipos de encapsulamento do PLD EP1800 da ALTERA| PackagePinOut_EP1810.png| 400 px | https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ds/archives/classic.pdf }}
<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''':
{{fig|2.9|Architetura do CPLD MAX 5000 da ALTERA| max_5000_architecture.jpg| 400 px | https://www.altera.com/solutions/technology/system-design/articles/_2013/in-the-beginning.html}}
<syntaxhighlight lang=vhdl>
{{collapse bottom}}
[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''':
;PARA O PRÓXIMO ENCONTRO:
<syntaxhighlight lang=vhdl>
*[https://youtu.be/7qa1dsCpMMo Memória EEPROM e FLASH] , [https://youtu.be/yLyQRtybfhc EEPROMs Market Value Explained] - Microchip (ingles)
[rótulo:] [FOR identificador IN faixa] LOOP
*[https://www.youtube.com/watch?v=BA12Z7gQ4P0 Using an EEPROM to replace combinational logic] -
            afirmação_sequencial;
*[https://www.intel.com/content/www/us/en/programmable/customertraining/webex/PLDBasics_History/presentation_html5.html History of Programmable Logic] Intel
            NEXT [rótulo] [WHEN condição];    -- Se a "condição" é verdadeira, não executa as linhas até a linha "END LOOP"
*[https://www.intel.com/content/www/us/en/products/details/fpga/platforms.html See why Microsoft chose Intel FPGAs to accelerate their next generation cloud infrastructure]
                                              -- e incrementa o "identificador".
*[https://www.intel.com/content/www/us/en/products/docs/programmable/text-speech-synthesis-demo.html Text to Speech Synthesis Demo Using Stratix® 10 NX FPGA]
            afirmação_sequencial;
*Seção 4.1 a 4.5 de [http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf Review of Field Programmable Gate Arrays (FPGAs)], Volnei A. Pedroni. (ou para quem preferir em português, leia as seções 18.1 a 18.3 do livro: PEDRONI, Volnei A '''Eletrônica Digital Moderna e VHDL: Princípios Digitais, Eletrônica Digital, Projeto Digital, Microeletrônica e VHDL'''; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. ISBN 9788535234657. Têm 16 exemplares na [http://biblioteca.ifsc.edu.br/index.asp?codigo_sophia=30631 biblioteca do Campus]. Número de chamada: 621.392 P372e)
            ...
*Seção 2.1 Dispositivos lógicos programáveis do TCC [[Integração de ramais analógicos com FPGA utilizando processador softcore]], Renan Rodolfo da Silva.
          END LOOP [rótulo];
</syntaxhighlight>


*Instrução '''CASE''' 
;Encontro 4 (27 mar.):
<syntaxhighlight lang=vhdl>
* Arquitetura de FPGAs (Xilinx e Altera): CLB, LAB, LUT, Flip_flop D, RAM, DSP, Clock, PLL, DLL, I/O
[rótulo opcional:] CASE expressão IS
:FONTE: [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA
                  WHEN valor =>                            -- valor único
                    afirmação_sequencial;                           
                    afirmação_sequencial;                           
                    ...
                  WHEN valor1 | valor2 | ... | valorN  =>  -- lista de valores
                    afirmação_sequencial;                           
                    afirmação_sequencial;                           
                    ...
                  WHEN valor1 TO valor2 =>                  -- faixa de valores
                    afirmação_sequencial;                           
                    afirmação_sequencial;
                    ...
                  WHEN OTHERS  =>                          -- para evitar latches
                    afirmação_sequencial;                           
                    afirmação_sequencial;
                    ...
          END CASE;
</syntaxhighlight>


;Exemplos:
{{collapse top | expand=true |Exemplos de FPGA}}
* Leading Zeros (LOOP com EXIT) (Ex 6.5)  - Esse circuito deve determinar quantos zeros tem em um vetor de entrada '''Data''' 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>
{{fig|2.9|Arquitetura de um FPGA | Architecture_FPGAs.png| 600 px | https://www.intel.com/content/www/us/en/docs/programmable/683176/18-1/fpga-overview-opencl-standard.html}}
entity leading_zeros is
generic (N : natural := 8);
port
( ________ : in std_logic_vector(0 to N-1);
count : out integer range 0 to N
);
end entity;


architecture ____ of leading_zeros is
{{fig|2.10|Diagrama simplificado da ALM de um FPGA Intel/Altera | ALM_LUT_FPGAs.png| 600 px | https://www.intel.com/content/www/us/en/content-details/771003/fpga-architecture-8-input-lut-legacy-white-paper.html}}


begin
{{fig|2.11|Arquitetura interna de uma LUT | LUT_FPGAs.png| 800 px | [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA}}
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>
{{fig|5.15|Simulação do leading_zeros| SIM_LZ.png| 800 px | }}


* Contador de zeros (LOOP com NEXT ou apenas LOOP)  - Esse circuito deve determinar quantos zeros tem em um vetor de entrada '''Data'''.
{{fig|2.12|Configuração de uma LUT | LUT_FPGAs_Config.png| 1000 px | https://www.allaboutcircuits.com/technical-articles/purpose-and-internal-functionality-of-fpga-look-up-tables/}}
:*Fazer a síntese do circuito; fazer simulação no Modelsim; analisar a forma como o compilador implementou o incrementador.
 
{{fig|5.16|Simulação do counting_zeros| SIM_CZ.png| 800 px | }}
{{fig|2.13|Arquitetura do Cyclone® V Intel/Altera | CycloneV_FPGAs.jpg| 600 px | https://www.intel.com.br/content/www/br/pt/products/details/fpga/cyclone/v/article.html}}


*Ver pag. 161 a 164 de <ref name="PEDRONI2010b"/>
{{fig|2.14|Leiaute de um FPGA Xilinx genérico | Leiaute2_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }}


;Encontro 13  (5 abr.)
{{fig|2.15|Roteamento de sinal em um FPGA | Roteamento_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }}
* 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'''


Esse somador pode ser implementado tanto com código sequencial como com código concorrente. Note que no primeiro caso o bit de '''carry''' se definido como '''variable''' pode ser reaproveitado. No segundo caso é necessário criar um vetor completo para conectar os '''carry_out''' de um estágio ao '''carry_in''' do próximo.
{{fig|2.16|Tecnologias usadas na configuração de FPGAs| FPGA_programming.png| 800 px | https://www.sciencedirect.com/topics/computer-science/one-time-programmable }}
{{collapse bottom}}


<syntaxhighlight lang=vhdl>
:Ver também [https://www.youtube.com/watch?v=kU2SsUUsftA&t=2s SRAM], [https://www.youtube.com/watch?v=7qa1dsCpMMo EEPROM], [https://www.youtube.com/watch?v=ELl3abwYQ90&list=PL9B4edd-p2agcmJl2EscTdLudLv58uXHt&index=1 What Is Flash Memory]
library ieee;
use ieee.std_logic_1164.all;


entity carry_ripple_adder is
* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 1 e 2
generic (N : integer := 3);
port (
a, b : std_logic_vector (N-1 downto 0);
cin  : std_logic;
s    : out std_logic_vector (N-1 downto 0);
cout : out std_logic
);
end entity;


architecture estrutural_sequencial_v1 of carry_ripple_adder is
* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 3 e 4
begin
-- Uso de um codigo sequencial para geracao de um circuito combinacional
process (a, b, cin) is
variable c : std_logic;
begin
c := cin;
for i in 0 to N-1 loop
s(i) <= a(i) xor b(i) xor c;
c := (a(i) and b(i)) or (a(i) and c) or (b(i) and c);
end loop;
cout <= c;
end process;
end architecture;


architecture estrutural_concorrente_v1 of carry_ripple_adder is
;PARA O PRÓXIMO ENCONTRO:
signal c : std_logic_vector(N downto 0);
* Leia a assista a alguns dos vídeos sobre a historia e processo de produção dos chips.
begin
:*[https://www.semiwiki.com/forum/content/1535-brief-history-fabless-semiconductor-industry.html A Brief History of the Fabless Semiconductor Industry]
-- Uso de um codigo concorrente para geracao de um circuito combinacional
:*[http://www.semiwiki.com/forum/content/1539-brief-history-tsmc.html Taiwan Semiconductor Manufacturing Corporation (TSMC)], [http://www.globalfoundries.com/ GLOBALFOUNDRIES]
c(0) <= cin;
:*[https://www.linkedin.com/pulse/free-copy-fabless-transformation-semiconductor-industry-daniel-nenni-1 Fabless: The Transformation of the Semiconductor Industry, 2014] - Download free
l1: for i in 0 to N-1 generate
:*[https://www.youtube.com/watch?v=W3rfVpkNquA Produção do FinFET], [https://www.youtube.com/watch?v=d9SWNLZvA8g]
s(i) <= a(i) xor b(i) xor c(i);
:*[https://en.wikipedia.org/wiki/3_nm_process 3 nm process], [https://en.wikipedia.org/wiki/Multigate_device multi-gate MOSFET]
c(i+1) <= (a(i) and b(i)) or (a(i) and c(i)) or (b(i) and c(i));
:*[https://www.youtube.com/watch?v=UvluuAIiA50 GLOBALFOUNDRIES Sand to Silicon], [https://www.youtube.com/watch?v=F2KcZGwntgg How Microchips are made] - Processo de fabricação de um chip
end generate;
:*[https://en.wikipedia.org/wiki/Foundry_model Foundries], [https://en.wikipedia.org/wiki/List_of_semiconductor_fabrication_plants List of semiconductor fabrication plants]
cout <= c(N);
:*[https://www.youtube.com/watch?v=GU87SH5e0eI A dependência do mundo com a TMSC]
end architecture;
:*[https://www.youtube.com/watch?v=kU2SsUUsftA What is SRAM?], [https://www.youtube.com/watch?v=Lozf9sceW_o What is DRAM?] - Microchip
</syntaxhighlight>
 
;Encontro 5 (1 abr.):
* System on Chip
{{fig|2.17|Altera - Visão geral do dispositivo Arria V SX e ST| ArriaV_SX_ST_Chip.png| 800 px | https://br.mouser.com/datasheet/2/612/av_51001-1623623.pdf}}


{{fig|5.17|RTL do carry_ripple_adder de 3 bits | RTL_carry_ripple_adder3.png| 800 px |}}
{{fig|2.18|Altera - Agilex 7 SoCs HPS Digrama de Blocos| Agilex7SoC_Blocos.png| 800 px | https://static6.arrow.com/aropdfconversion/b568cfe009abfed6a28eff56700189883d7fc179/ag-overview-683458-666707.pdf}}


*Instrução '''WAIT''': WAIT UNTIL, WAIT FOR (simulação apenas),  WAIT ON (não implementada no Quartus II).  
* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 1 a 4


<syntaxhighlight lang=vhdl>
;PARA O PRÓXIMO ENCONTRO:
  [rótulo:] WAIT UNTIL <condition>;
:* Ver preços de DLPs em
[rótulo:] WAIT ON sensitivity_list;
::*[https://www.arrow.com/ ARROW]
[rótulo:] WAIT FOR time_expression;
::*[https://www.digikey.com/ Digikey]
</syntaxhighlight>
::*[https://mouser.com Mouser Electronics]
::*[https://www.newark.com/ Newark]
:* Fabricantes de DLPs/FPGAs e familias de DLPs atuais.
::*[https://www.altera.com/products/fpga/overview.html ALTERA/INTEL] - Stratix, Arria, Cyclone, Max, Agilex
::*[https://www.xilinx.com/products/silicon-devices/fpga.html Xilinx/AMD] - Virtex, Kintex, Artix, Zynq (SoC)
::*[https://www.microchip.com/en-us/products/fpgas-and-plds/fpgas Microchip] - Igloo, PolarFire
::*[http://www.latticesemi.com/Products.aspx#_D5A173024E414501B36997F26E842A31 Lattice]  - ECP, iCE, Mach


: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'''.


* Projetar um contador em BCD entre 0 e 99 ('''countBCD_DU.vhd'''), com entrada de clock, reset e saidas unidade(0 a 9) e dezena (0 a 9). Projete o contador para parar em qualquer valor de DU onde D é a dezena e U é a unidade.
;Encontro 6 (3 abr.):
 
* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 1 a 4
:* versão 1 - contagem crescente.
-->
{{fig|5.18|RTL do contador BCD 00 a 99 | RTL_countBCD00-99.png| 800 px |}}
{{collapse bottom}}
{{fig|5.19|Simulação do contador BCD 00 a 99 | MODELSIM_countBCD00-99.png| 800 px |}}
 
;DESAFIO:
Implementar um contador BCD de 00 a 99, com parada em qualquer valor MAX_DU. Onde se D = 5, U = 9, implica em contar de 000 até 59 e ficar parado neste valor. A atingir o valor final MAX_DU, uma saída adicional OPA deve ser ativada.
*Versão 1: O contador crescente deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com parada em MAX_DU.
*Versão 2: O contador crescente deve fazer a contagem em binário, e incrementar 6 nos bits da unidade sempre que passar de 9(1001) para 10 (1010), com parada em MAX_DU.
*Versão 3: O contador decrescente deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com início em MAX_DU e parada em 00.
 
;Encontro 14  (9 abr.)
*Instrução '''IF GENERATE'''


===Unidade 3 - Circuitos sequenciais (Implementação com HDL) ===
* 18 ENCONTROS
{{collapse top | expand=true | Unidade 3 - Circuitos sequenciais (Implementação com HDL)}}
<!--
;Encontro 6 (3 abr.):
*Flip-Flop e circuitos sequenciais.
:*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>
<syntaxhighlight lang=vhdl>
<generate_label>:  
[rótulo:] PROCESS [(lista_de_sensibilidade)] [IS]
if <condition> generate
            [parte_declarativa]
-- Concurrent Statement(s)
        BEGIN
end generate;
            afirmação_sequencial;
            afirmação_sequencial;
            ...
        END PROCESS [rótulo];
</syntaxhighlight>
</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];


Essa instrução é utilizada para a geração condicional de código durante a elaboração. Com isso, partes do projeto são sintetizadas e outras não, dependendo de certas condições ou parâmetros definidos no projeto. Como ela faz parte do grupo de instruções concorrentes, ela não pode ser utilizada dentro de PROCESS, FUNCTION ou PROCEDURE.
</syntaxhighlight>
 
:*Exemplos:
Para exemplificar, consideramos a situação em que um contador crescente (UP) OU um contador decrescente (DOWN) devem serm utilizados, mas o contador nunca será aplicado nas duas direções de contagem.  Neste caso, é possível estabelecer um parâmetro  '''GENERIC''', que definirá se a contagem é UP ou DOWN. Analise o código a seguir:
::* DFFs com Reset Assincrono e Reset Sincrono, com Enable, com Preset (Variação Ex 6.1).
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
entity contador_up_down is
--Flip Flop tipo D com reset assincrono, sensivel a borda de subida.
generic
process (clock,reset)
(
MIN : natural := 3;
MAX : natural := 21;
UPDOWN : natural := 0 -- 0 => up; 1 => down
);
port
(
clk, rst   : in std_logic;
count_out  : out integer range MIN to MAX
);
end entity;
 
architecture ifsc_v1 of contador_up_down is
begin
begin
L1: if UPDOWN = 0 generate
  if (reset = '1') then
process (clk, rst)
      q <= '0';
variable cnt : integer range MIN to MAX;
-- elsif (clock'event and clock = '1') then or
begin
  elsif (rising_edge(clock)) then
if rst = '1' then
      q <= d;
cnt := MIN;
  end if;
elsif (rising_edge(clk)) then
end process;
if cnt = MAX then
</syntaxhighlight>
cnt := MIN;
{{fig|3.1|RTL de Flip-flop D de borda de subida, com reset assíncrono| FF_D_RST.png| 400 px | }}
else
<syntaxhighlight lang=vhdl>
cnt := cnt + 1;
--Flip Flop tipo D com preset assincrono e sinal de enable, sensivel a borda de descida.
end if;
process (clock, preset)
end if;
begin
count_out <= cnt;
  if (preset = '1') then
end process;
      q <= '1';
end generate;
  elsif (falling_edge(clock)) then
L2: if UPDOWN = 1 generate
      if (enable = '1') then
process (clk, rst)
        q <= d;
variable cnt : integer range MIN to MAX;
      end if;
begin
  end if;
if rst = '1' then
end process;
cnt := MAX;
</syntaxhighlight>
elsif (rising_edge(clk)) then
{{fig|3.2|RTL de Flip-flop D de borda de descida, com preset assíncrono e enable| FF_D_PRST.png| 400 px | }}
if cnt = MIN then
::* Comparar com Latch (sem clk'event).
cnt := MAX;
<syntaxhighlight lang=vhdl>
else
--Latch tipo D com reset assincrono.
cnt := cnt - 1;
process (enable, reset, d)
end if;
begin
end if;
  if (reset = '1') then
count_out <= cnt;
      q <= '0';
end process;
  elsif (enable='1')) then
end generate;
      q <= d;
end architecture;
  end if;
end process;
</syntaxhighlight>
</syntaxhighlight>
Se o parâmetro '''UPDOWN''' for instanciado com 0, teremos um contador crescente.  Caso seja instanciado com 1, o contador será decrescente.  Veja a simulação nos dois casos.
{{fig|3.3|RTL de Latch D de com reset assíncrono e enable ativo alto| LATCH_D_RST.png| 400 px | }}
{{fig|5.20|Simulação do contador UPDOWN com 0 | MODELSIM_countUP.png | 800 px |}}
* Na figura abaixo, note que o Latch é implementado utilizando a LUT do elemento lógico do FPGA, enquanto que o Flip-flop utiliza o componente já disponível neste elemento lógico.
{{fig|5.21|Simulação do contador UPDOWN com 1 | MODELSIM_countDOWN.png | 800 px |}}
*[[Evite os latches no projeto]]


;DESAFIO:
{{fig|3.4|Comparação do ''Technology Map'' de um Latch_D (esquerda) com FF_D (direita)| FF_D_LATCH_D.png| 800 px | }}
* Projetar um divisor de clock que dado um clock de entrada de f Hz, produza na saída um sinal de clock de f/N onde N é um número inteiro ('''div_clk_N''')
:* Utilize esse circuito para obter um clock de 1 Hz a partir do sinal de 50MHz existente no kit DE2-115.
:* Utilize um segundo circuito para obter um clock de 0,1 Hz
:* Teste o circuito no kit DE2-115.


*Projetar um conversor de BCD para SSD - display de sete segmentos ('''BCD2SSD.vhd''').  O circuito deve ter uma entrada que permite escolher se o display é do tipo anodo comum ou catodo comum, utilizano a instrução IF GENERATE.
:* Ver pag. 151 a 156 de <ref name="PEDRONI2010b"/>
:* Ver [https://tinyurl.com/2xu3vwd7 simulação de Latch tipo D] (Falstad)
:* Ver [https://tinyurl.com/2al6kkbs simulação de Flipflop tipo D] (Falstad)
:* Ver [[Especificando o valor de Power-Up do flip-flop D]]


;Encontro 15, 16 e 17  (12, 13 e 19 abr.)
<syntaxhighlight lang=vhdl>
*Otimização de circuitos sequenciais
-- Flip Flop tipo D com reset síncrono sensível a borda de subida.
*Registradores de deslocamento
-- Modifique a descrição para que o reset_ass seja assíncrono e reset_sinc seja síncrono.
*Simulação do circuito
-- Note que a função rising_edge(clock) é equivalente a (clock'event and clock'last_value = '0' and clock = '1'))


;Encontro 18  (23 abr.)
process (clock, reset)
*Temporizações de um Flip-Flop.
begin
:*atraso do clock para saída (Tcq)
  if (reset = '1') then
:*tempo de setup (T_{setup}) e tempo de hold (T_{hold})
      q <= '0';
{{fig|5.22|Temporizações de um Flip Flop | FF_timing.png | 600 px | RTL Hardware Desing, P. Chu }}
  elsif (clock'event and clock'last_value = '0' and clock = '1')) then
'''Nota:''' a violação do tempo de setup ou hold leva ao estado de meta-estabilidade, na qual a saída fica temporariamente em um valor indefenido.
      q <= d;
*Os circuitos devem ser projetos para serem globalmente síncronos.
  end if;
end process;
</syntaxhighlight>
{{fig|3.5|RTL do Flip-flop D com reset assíncrono e reset síncrono| FF_D_RST_SINC_ASINC.png| 400 px | }}
*[[Como evitar o uso da lógica combinacional no reset síncrono]]


Exemplos de contadores com projeto Sincrono.
;Encontro 7 (8 abr.):
*Contador de sequencia arbitraria (implementado com when else)
*Contador de livre com indicação de valor máximo. (implementado com incrementador)
*Contador com opções de clear sincrono, load, e parada
*Contador de modulo 10.


;Encontro 19 (26 abr.)
*Exercício: Implemente um registrador com N FF_D no lugar de um único FF_D.  
*Violação do tempo de Setup do FF e frequência máxima do circuito (Fmax).
{{fig|3.6|RTL do Registrador (de 4 bits) com reset assíncrono| REG_RST.png| 400 px | }}
{{fig|5.23|Modelo de Circuito Sequencial | SequencialCktModel.png | 800 px | RTL Hardware Desing, P. Chu }}
{{fig|3.7|Techonogy Map do Registrador (de 4 bits) com reset assíncrono| TM_REG_RST.png| 400 px | }}
* Faça a simulação funcional do DFFs e do Latch


{{fig|5.24|Tempo de Setup e Fmax | SetupxFmax.png | 1000 px | RTL Hardware Desing, P. Chu }}
;Para o próximo encontro:
*Use o script do arquivo de simulação tb_FFD_v_ruim.do para repetir a simulação feita em aula.
*Melhore o script eliminando comentários desnecessários.
*Deixe no inicio do script os comandos (alguns estarão comentados)
vlib rtl_work
:Função: Criar uma biblioteca de trabalho chamada rtl_work.
vmap work rtl_work
:Função: Faz o mapeamento da biblioteca padrão work para a biblioteca rtl_work criada anteriormente.
vcom -93 -work work {../../FFD_N.vhd}
:Função: Compila o arquivo VHDL FFD_N.vhd utilizando o padrão VHDL-93, e coloca o resultado da compilação na biblioteca work.
vsim work.ffd_n(ifsc_v1)
:Função: Inicia a simulação do componente ffd_n, presente na biblioteca work, utilizando a configuração ifsc_v1.
add wave -r sim:/ffd_n/*
:Função: Adicione todos os sinais da hierarquia a janela Wave.


{{fig|5.25|Equações do Tempo de Setup e Fmax (1/Tc(min)) | EquationSetupxFmax.png | 600 px | RTL Hardware Desing, P. Chu }}
*Para cada estímulo (entrada) faça com que haja apenas uma linha de comando '''force''' usando o padrão abaixo:
force -freeze sim:/ffd_n/<nome do estimulo> valor1 tempo1, valor2 tempo2, valor3 tempo3
*Para a entrada '''clock''' use:
force -freeze sim:/ffd_n/clock v1 t1, v2 t2 -r Tclk
:onde:
::o primeiro par (v1 t1) indica o valor inicial do clock v1 = 1 => começa ALTO.  v1 = 0 => começa BAIXO.  t1 é normalmente 0, indica quando o valor v1 deve ser gerado.
::o segundo par (v2 t2) indica o valor final do clock, v2 deve ser o complemento de v1. t2 é a duração do valor v1 em ps (ou outra unidade)
::o tempo Tclk é o período em que o sinal deve ser repetido.
:Exemplo de um sinal de período de 100ps => fclk = 10GHz;
force -freeze sim:/ffd_n/clock 1 0, 0 50 -r 100
*Conclua a simulação com uma linha de '''run''' que seja suficiente para variar todos os estímulos e obter os resultados:
run XXX ps ou 
run XXX ns|us|ms|sec|min|hr
*Para visualizar todo o período de tempo simulado inclua o seguinte comando no script
wave zoom full


{{fig|5.26|Equações do Tempo de Hold | EquationHold.png | 600 px | RTL Hardware Desing, P. Chu }}
*Ao final crie o arquivo FFD_N.qar que deve conter além dos arquivos de projeto, também os dois scripts de simulação. Use o Quartus para incluir esses arquivos e gerar o qar.  Confira o seu conteúdo no arquivo FFD_N.qarlog
<pre>
=========== Files Selected: ===========
/home/moecke/ELD2/2025.1/AULA7/FFD_N.qpf
/home/moecke/ELD2/2025.1/AULA7/FFD_N.qsf
/home/moecke/ELD2/2025.1/AULA7/FFD_N.vhd
/home/moecke/ELD2/2025.1/AULA7/simulation/modelsim/tb_FFD_v2_melhor.do
/home/moecke/ELD2/2025.1/AULA7/simulation/modelsim/tb_FFD_v_ruim.do
/opt/intelFPGA/20.1/quartus/linux64/assignment_defaults.qdf
======= Total: 6 files to archive =======
</pre>


{{fig|5.27|Atraso da saída | EquationOutputDelay.png | 600 px | RTL Hardware Desing, P. Chu }}
;Encontro 8(10 abr.):
*[https://drive.google.com/file/d/1O7zeVBDCJ_qKp6QTugiO0ax7N3nzGVjP/view?usp=drive_link Projeto de Circuitos Sequenciais: Princípios] Slides do prof. Roberto de Matos
;Circuito síncrono vs assíncrono:
Tipo de Circuito Características
*Síncrono: Usa flip-flops com um clock global comum. Estados mudam apenas na borda do clock.
*GALS (Globally Asynchronous, Locally Synchronous): Módulos internos síncronos com seus próprios clocks, mas sem sincronismo global. Comunicação entre módulos requer cuidados especiais.
*Assíncrono: Não utiliza clock. As transições de estado dependem apenas das mudanças nas entradas e no tempo de propagação dos sinais. Difícil de projetar corretamente.
*Circuito globalmente síncrono: todos os elementos de memória (D FFs) controlados (sincronizados) por um sinal de clock global comum.
*Circuito globalmente assíncrono, mas localmente síncrono (GALS).
*Circuito globalmente assíncrono: Usa DFF, mas não um clock global. Não usa sinal de clock.
Um dos aspectos de projeto mais difíceis de um circuito sequencial é satisfazer as restrições (constraints) de tempo (ex.: Tsetup e Thold). No MÉTODO SÍNCRONO, todos os DFFs utilizam em um único clock.  Assim apenas é necessário lidar com a restrição de tempo de um elemento de memória.
;Circuito Sequencial Síncrono - Diagrama Conceitual:
{{fig|5.21|Diagrama conceitual de circuitos síncronos | Concept_RT.png | 600 px | <ref name="CHU2006"> CHU, P. P. '''RTL Hardware Design Using VHDL: Coding for Efficiency, Portability, and Scalability'''. 1a ed. [S.l]:Wiley-IEEE Press, 2006. 694p. ISBN 9780471720928.</ref> }}


Exemplos de outros contadores com projeto síncrono.
*'''External Input''': Entradas externas fornecem os sinais que afetam a transição entre estados.
*Contador de modulo m (onde m é uma entrada).
*'''Next-State Logic''' (lógica de próximo estado): Circuito combinacional que determina qual será o próximo estado (state_next) com base no estado atual (state_reg) e nas entradas externas.
:- Versão two_seg_clear_arch (12 EL, Fmax = 542,89 MHz para Slow 1,2V 125C Model)
*'''State Register''' (registrador de estado): Elemento de memória (Flip-Flop tipo D) que armazena o estado atual. Ele captura o valor de state_next na borda ativa do sinal de clock (clk).
:- Versão two_seg_effi_arch  (8 EL, Fmax = 444,64 MHz para Slow 1,2V 125C Model)
* '''Output Logic''' (lógica de saída): Circuito combinacional que gera as saídas do sistema com base no estado atual. Pode ou não depender das entradas (Moore vs Mealy):
: O contador realiza '''m''' contagens, e precisa log2(m) registradores (flip-flops)
:*'''Moore''': Saída depende apenas do estado.
:*'''Mealy''': Saída depende do estado e das entradas.


:Funcionamento - Fluxo de dados:
*O sinal de clock (clk) sincroniza todas as mudanças de estado.
*O registrador atualiza seu valor na borda do clock, armazenando o ''state_next'' calculado anteriormente.
*A lógica combinacional (tanto de próximo estado quanto de saída) opera continuamente, processando entradas e o estado atual.
*O sistema avança de estado apenas no clock, garantindo que as transições ocorrem de forma ordenada e previsível.
* Glitches não tem efeitos na saída, desde que o ''state_next'' esteja estável quando ocorre a borda de subida do clock, e ''Tsetup'' e ''Thold'' sejam respeitados.


;Encontro 20  (30 abr.)
;Encontro 9 (15 abr.):
*Contador Gray (só troca um bit por vez)
*[https://drive.google.com/file/d/1O7zeVBDCJ_qKp6QTugiO0ax7N3nzGVjP/view?usp=drive_link Projeto de Circuitos Sequenciais: Princípios] Slides do prof. Roberto de Matos
: ver [[Código Gray]]
*Contador binário livre com pulso de máximo
: Contagens ?
:*Código com 2 segmentos: 1) parte sequencial (apena atualiza o r_reg) 2) parte combinatória (cálcula o r_next)  
*Contador em anel (desloca um padrão inicial)
:*Código com 1 segmento: todo o código fica em um único process.
: (4 EL, Fmax = 1085,78 MHz para Slow 1,2V 125C Model)
*Contador decimal (mod-10)
: Contagens ?
*Analisar a diferença entre utilizar signal e variable.  O signal é atualizado apenas ao final do process (end process), enquanto que a variable é atualizada imediatamente. Essa diferença pode gerar códigos que não fazem exatamente o que desejamos.
*Contador Johnson
;DOIS segmentos vs. UM segmento:
: (4 EL, Fmax = 1086,96 MHz para Slow 1,2V 125C Model)
*Código de dois segmentos
: Contagens com 4 bits (8 valores 0111, 0011, 0001, 0000, 1000, 1100, 1110, 1111)
:*Separa o segmento de memória do resto do código;
*Contador LFSR (Linear Feedback Shift Register)
:*Pode ser um pouco complicado (lógica separada);
:- Versão no_zero_arch (4 EL, Fmax = 909,92 MHz para Slow 1,2V 125C Model)
:*Tem um mapeamento claro para o componente de hardware.
:- Versão with_zero_arch (4 EL, Fmax = 773,99 MHz para Slow 1,2V 125C Model)
*Código de um segmento
: Contagens ?
:*Mistura o segmento de memória e lógica de próximo estado/lógica de saída;
:*Em alguns casos pode ser mais compacto;
:*Mapeamento de hardware não é claro;
:*'''Propenso a erros'''.


No exemplo do contador binário livre com pulso de máximo é possível perceber um dos tipos de erros que o uso de código em um segmento pode gerar.  Como cada atribuição feita a um sinal dentro do '''if rising_edge(clk) then''', gera um flip-flop para a saida '''max_pulse''', e pode causar atrasos indesejados em sinais.


;Encontro 21  (3 mai.)
<syntaxhighlight lang=vhdl>
*Contador BCD
architecture extra_ff_max_pulse of binary_counter4_pulse is
:- Versão concurrent_arch (20 EL, Fmax = 426,08 MHz para Slow 1,2V 125C Model)
  signal r_reg: unsigned(3 downto 0);
:- Versão if_arch  (15 EL, Fmax = 371,89 MHz para Slow 1,2V 125C Model)
begin
  process(clk,reset)
  begin
      if (reset='1') then
        r_reg <= (others=>'0');
      elsif rising_edge(clk) then
        r_reg <= r_reg + 1;
        if r_reg="1111" then
            max_pulse <= '1';
        else
            max_pulse <= '0';
        end if;
      end if;
  end process;
  q <= std_logic_vector(r_reg);
end architecture;
</syntaxhighlight>
{{fig|5.22|Diagrama RTL contador com max_pulse output | max_pulse_RTL.png | 600 px |  }}


{{fig|5.22|Diagrama RTL contador com extra flip-flop in max_pulse output | FF_max_pulse_RTL.png | 600 px |  }}


<blockquote style="background: yellow; border: 3px solid black; padding: 1em;">
{{fig|5.23|Simulação do extra flip-flop in max_pulse output - errado| FF_max_pulse_SIM.png | 600 px | }}
;CALENDÁRIO FOI SUSPENSO NO CAMPUS: Entre 6 mai. e 28 jun as '''aulas foram proibidas'''. Foram ao todo 15 encontros suspensos em função da suspensão do calendárioAs aulas serão repostas de acordo com o calendário de reposição a ser aprovado pelo campus.
<pre>
O Colegiado do Câmpus São José decidiu suspender o calendário acadêmico local a partir de 6 de maio (segunda-feira), em função da greve dos servidores do IFSC. A decisão foi publicada na Resolução 03/2024, de 30 de abril.


Sendo assim, considerando o termo de acordo supracitado, em conjunto com a suspensão do calendário acadêmico pelo câmpus, esclareço que NENHUMA AULA, PROVA, projeto de extensão ou qualquer outra atividade vinculada ao calendário acadêmico DEVERÁ OCORRER enquanto perdurar o período de suspensão do mesmo.
{{fig|5.24|Simulação do max_pulse output - correto | max_pulse_SIM.png | 600 px |  }}
</pre>
</blockquote>


No exemplo do contador decimal (mod-10) é possível perceber um outro tipo de erros que o uso de código em um segmento pode gerar.
Como um '''sinal (signal) é atualizado apenas no final do processo''', isso pode levar a códigos com erro como mostrado no exemplo a seguir.


;Encontro 22  (2 jun.)
<syntaxhighlight lang=vhdl>
*Revisão de alguns circuitos sequencias síncronos.
architecture one_seg_arch_signal of mod10_counter is
*Simular cada um deles e analisar as contagens.
  constant TEN: integer := 10;
;PARA O PRÓXIMO ENCONTRO:
  signal r_reg: unsigned(3 downto 0);
*Estude a lista de exercícios proposta para a avaliação A1.
begin
  -- register
  process(clk,reset)
  begin
      if (reset='1') then
        r_reg <= (others => '0');
      elsif rising_edge(clk) then
r_reg <= r_reg + 1;
if r_reg=TEN then
r_reg <= (others => '0');
end if;
      end if;
  end process;
  -- output logic
  q <= std_logic_vector(r_reg);
end architecture;
</syntaxhighlight>


Na comparação '''r_reg=TEN''', espera-se que o r_reg tenha sido incrementado ('''r_reg <= r_reg + 1'''), mas o valor de r_reg ainda é o valor que tinha ao entrar no process. Assim o contador acaba contando de 0 a 10 e não de 0 a 9.


;Encontro 23  (5 jun.)
*'''Circuito de PWM''' (''Pulse Width Modulation'' - Modulação por largura de pulso)
:*Em algumas aplicações ao invés de usar diretamente a contagem, se usa o estado do contador para geram sinais de saída. Um exemplo é um circuito de modulação por largura de pulso (PWM), que gera um pulso de saída com um ciclo de trabalho ajustável.
:*Por exemplo, em um circuito PWM que tem 16 passos, o ciclo de trabalho pode ser ajustado em incrementos de 1/16, ou seja, o ciclo de trabalho pode ser 1/16, 2/16, 3/16, ..., até 16/16. Este circuito pode ser implementado por um contador mod-16 com um circuito de saída especial, que define o valor da saída em alto de acordo com o valor da contagem. O período dos pulsos de saída neste caso sempre será de 16 vezes o período do relógio. Um código VHDL para este circuito é mostrado na [https://moodle.ifsc.edu.br/pluginfile.php/399099/mod_resource/content/4/list_09_14_pwm.vhd Listagem 9.14 do livro do P. Chu].
:*Note que uma expressão booleana adicional, w="0000", é incluída para acomodar a condição especial.
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
   buf_next <= '1' when (r_reg<unsigned(w)) or (w="0000") else '0';
architecture one_seg_arch_variable of mod10_counter is
</syntaxhighlight>
  constant TEN: integer := 10;
{{fig|5.X|RTL do circuito de PWM| PWM_RTL.png| 600 px | }}
begin
Na simulação abaixo, um clock de 50 ps foi utilizado, e o '''valor da entrada w''' foi definida como (3, 8, 0, 1, 15) a cada 1600 psNote que a largura do pulso da '''saída pwm_pulse''' está de acordo com aquela entrada.
  -- register
{{fig|5.X|Simulação do circuito de PWM| PWM_SIM.png| 1000 px | }}
   process(clk,reset)
variable r_reg: unsigned(3 downto 0);
  begin
      if (reset='1') then
        r_reg := (others => '0');
      elsif rising_edge(clk) then
r_reg := r_reg + 1;
if r_reg = TEN then
r_reg := (others => '0');
end if;
      end if;
      -- output logic
  q <= std_logic_vector(r_reg);
  end process;
end architecture;
</syntaxhighlight>
A solução acima utiliza '''variable''' no lugar de '''signal''' para o r_regNeste caso a comparação '''r_reg = TEN''' irá comparar corretamente o valor atual de r_reg já incrementado ('''r_reg := r_reg + 1'''), e a contagem será correta de 0 a 9.


;Encontro 24  (9 jun.)
;Para o próximo encontro:
* Registradores como armazenamento temporário
*Implementar um contador BCD que efetue a contagem de 000 a 999. O contador deve ter uma entrada de '''enable''' que habilita a contagem, além das entradas de '''reset''' (assincrono) e '''clock'''. O contador deve ter 3 saídas de 4 bits '''std_logic_vector(3 downto 0)''', uma para '''unidade''', uma para '''dezena''' e outra para a '''centena'''.
<!--
*O código deverá ser implementado em 2 segmentos separados. Um contendo apenas a parte sequencial ('''state register'''), e outro  contendo a parte combinacional. A parte combinacional deve ter a  '''next state logic''' e em separado a '''output logic'''.
*Implementar um contador [https://en.wikipedia.org/wiki/Linear-feedback_shift_register LFSR] de n bits.
*Exemplo do que pode ter no state register:
*Consultar [https://users.ece.cmu.edu/~koopman/lfsr/] ou a página 5 de [https://docs.amd.com/v/u/en-US/xapp052] para obter os termos que são usados na realimentação.
<syntaxhighlight lang=vhdl>
-->
-- state register
{{collapse bottom}}
  process(clock,reset)
  begin
      if (reset='1') then
        centena_reg <= (others=>'0');
        dezena_reg <= (others=>'0');
        unidade_reg <= (others=>'0');
      elsif rising_edge(clock) then
        centena_reg <= centena_next;
        dezena_reg <= dezena_next;
        unidade_reg <= unidade_next;
      end if;
  end process;
</syntaxhighlight>




===Unidade 4 - Maquinas de Estado Finitas===
;Encontro 10 (17 abr.):
*[https://drive.google.com/file/d/1O7zeVBDCJ_qKp6QTugiO0ax7N3nzGVjP/view?usp=drive_link Projeto de Circuitos Sequenciais: Princípios] Slides do prof. Roberto de Matos


{{collapse top | expand=true | Unidade 4 - Maquinas de Estado Finitas}}
*Variações do contador BCD
;Encontro 28  (23 jul.)
:*Em 2 segmentos com WHEN ELSE
* O que é uma FSM - Finite State Machine
:*Em 2 segmentos com IFs aninhados
{{fig|4.1|Exemplo de diagrama de estados de uma FSM Fig4.1(a) e implementação em hardware da FSM Fig4.2(a)|Fig11_1_FSM.png|800 px|Figura 11.1 e 11.2 de <ref name="PEDRONI2010b"/>}}
*Registrador de Deslocamento
* Modelo básico em VHDL de FSM
Abaixo estão três formas distintas de implementar um registrador de deslocamento, todas com a mesma funcionalidade, mas com diferenças na legibilidade, generalização e estilo de codificação:
:*Usando operador de concatenação:
<syntaxhighlight lang=vhdl>
r_next <= d & r_reg(3 downto 1);
q <= r_reg(0);
</syntaxhighlight>
Essa abordagem é compacta e permite facilmente estender o registrador para um número genérico de bits.
:* Atribuições bit a bit (sem laço):
<syntaxhighlight lang=vhdl>
r_next(3) <= d;
r_next(2) <= r_reg(3);
r_next(1) <= r_reg(2);
r_next(0) <= r_reg(1);
q <= r_reg(0);
</syntaxhighlight>
Apesar de ser explícita e didática, essa forma não é escalável, pois exige reescrever todas as atribuições para cada nova largura de registrador.
:*Atribuições bit a bit com '''for generate''':
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
LIBRARY ieee;
r_next(3) <= d;
USE ieee.std_logic_1164.ALL;
l1: for i in 2 downto 0 generate
----------------------------------------------------------
r_next(i) <= r_reg(i + 1);
ENTITY < entity_name > IS
end generate;
PORT (
q <= r_reg(0);
clk, rst : IN STD_LOGIC;
</syntaxhighlight>
entradas : IN < data_type > ;
Esta versão combina clareza com generalização. Assim como a primeira, é facilmente adaptável para registradores de qualquer tamanho.
saidas : OUT < data_type >);
 
END entity;
'''Observação:''' A primeira e a terceira implementações são mais adequadas quando se deseja gerar registradores de deslocamento de largura genérica, facilitando a reutilização do código. Já a segunda, apesar de simples, não é prática para registros maiores, pois não é escalável.
----------------------------------------------------------
 
ARCHITECTURE < architecture_name > OF < entity_name > IS
;Para o próximo encontro:
TYPE state IS (A, B, C, ...);
*'''DESAFIO''': Desenvolver um contador genérico capaz de contar em BCD com qualquer número de dígitos.
SIGNAL pr_state, nx_state : state;
 
-- ATTRIBUTE ENUM_ENCODING : STRING; --optional attribute
;Encontro 11 (22 abr.):
-- ATTRIBUTE ENUM_ENCODING OF state : TYPE IS "sequential";
:*Para replicar hardware várias vezes, utilize estruturas como: '''for generate''' ou  '''for loop'''
-- ATTRIBUTE SYN_ENCODING OF state : TYPE IS "safe";
*Instrução Concorrente '''FOR-GENERATE''':
BEGIN
<syntaxhighlight lang=vhdl>
------Logica Sequencial da FSM:------------
-- Note que neste caso o '''label''' é obrigatório
PROCESS (clk, rst)
 
BEGIN
label: FOR identificador IN faixa GENERATE
IF (rst = '1') THEN
  [Parte_Declarativa
pr_state <= A;
  BEGIN]
ELSIF rising_edge(clk) THEN
    afirmação_concorrente;
-- apenas na borda do "clk" ocorre a mudança de estado da FSM
    afirmação_concorrente;
pr_state <= nx_state;
    ...
END IF;
  END GENERATE [label];
END PROCESS;
</syntaxhighlight>
------Logica Combinacional da FSM:------------
 
PROCESS (pr_state, entradas)
*Instrução Sequencial '''FOR-LOOP''':
BEGIN
<syntaxhighlight lang=vhdl>
------Valores default das saidas------------
[rótulo:] FOR identificador IN faixa LOOP
                saidas <= < valor > ;
            afirmação_sequencial;
CASE pr_state IS
            afirmação_sequencial;
WHEN A =>
            ...
-- é necessário um WHEN para definir as "saidas" durante cada estado
          END LOOP [rótulo];
-- e analisar as "entradas" para definir o próximo estado
</syntaxhighlight>
saidas <= < valor > ;   -- apenas se diferente do valor default
 
IF (entradas = < valor >) THEN
*Implementar um registrador com N FF_D usando a instrução '''FOR GENERATE'''.
nx_state <= B;
 
...
{{fig|5.8|Technology Map de Shift Register| shift_reg_TM.png| 800 px | }}
ELSE
{{fig|5.9|Simulação de Shift Register| shift_reg_SIM.png| 800 px | }}
nx_state <= A;
 
END IF;
*Implementar uma porta or (and) ou xor de N entradas usando a instrução '''FOR GENERATE'''.
WHEN B =>
 
saidas <= < valor > ; -- apenas se diferente do valor default
Novas dicas para representar N dígitos BCD, cada um com 4 bits, será necessário criar um novo tipo de dado:
-- dependendo das "entradas", pode ser que hajam mais de um estados de destino
 
IF (entradas = < valor >) THEN
<syntaxhighlight lang=vhdl>
nx_state <= C;
  type bcd_digits is array (natural range <>) of unsigned(3 downto 0);
ELSIF (entradas = < valor >) THEN
  signal bcd  : bcd_digits(0 to N-1);
nx_state <= A;
</syntaxhighlight>
ELSE
:*Para utilizar esse tipo na declaração das portas (interface do componente), a declaração do tipo deve estar dentro de um pacote (package), e esse pacote deve ser importado no seu arquivo com:
nx_state <= B;
<syntaxhighlight lang=vhdl>
END IF;
library work;
WHEN C =>
use work.nome_do_pacote.all;
saidas <= < valor > ; -- apenas se diferente do valor default
</syntaxhighlight>
-- a passagem para outro estado pode não depender de nenhuma "entrada"
 
nx_state <= D;
;Para o próximo encontro:
WHEN ...
*'''DESAFIO''': Desenvolver um contador genérico capaz de contar em BCD com qualquer número de dígitos.
 
 
;Encontro 12 (24 abr.):
*Temporizações de um Flip-Flop.
:*atraso do clock para saída (Tcq)
:*tempo de setup (T_{setup}) e tempo de hold (T_{hold})
{{fig|5.22|Temporizações de um Flip Flop | FF_timing.png | 600 px |  <ref name="CHU2006"/> }}
'''Nota:''' a violação do tempo de setup ou hold leva ao estado de meta-estabilidade, na qual a saída fica temporariamente em um valor indefenido.
*Os circuitos devem ser projetos para serem globalmente síncronos.
 
*Violação do tempo de Setup do FF e frequência máxima do circuito (Fmax).
{{fig|5.23|Modelo de Circuito Sequencial | SequencialCktModel.png | 800 px |  <ref name="CHU2006"/> }}
 
{{fig|5.24|Tempo de Setup e Fmax | SetupxFmax.png | 1000 px |  <ref name="CHU2006"/> }}
 
{{fig|5.25|Equações do Tempo de Setup e Fmax (1/Tc(min)) | EquationSetupxFmax.png | 600 px |  <ref name="CHU2006"/> }}
 
{{fig|5.26|Equações do Tempo de Hold | EquationHold.png | 600 px |  <ref name="CHU2006"/> }}
 
{{fig|5.27|Atraso da saída | EquationOutputDelay.png | 600 px |  <ref name="CHU2006"/> }}


;Para o próximo encontro:
*ver [[Restringir a frequencia máxima de clock no Quartus]]
*Pensar em exemplos de contadores com projeto Sincrono.
:*Contador de sequencia arbitraria (implementado com when else)
:*Contador de livre com indicação de valor máximo. (implementado com incrementador) - Já feito
:*Contador com opções de clear sincrono, load, e parada
:*Contador de modulo 10 - Já feito
:*Contador de modulo m (onde m é uma entrada).


END CASE;
 
END PROCESS;
;Encontro 13 (29 abr.):
------Seção de Saída (opcional):-------
Instruções do tipo '''LOOP''': LOOP incondicional, '''FOR-LOOP''', '''WHILE-LOOP''', '''NEXT''', '''EXIT'''
-- Essa seção visa garantir que a saida new_output esteja sincronizada com o clk. 
 
-- Se isso não for importante, ela pode ser suprimida
*Instrução '''LOOP''' incondicional:
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
new_output <= < valor > ;
ELSIF rising_edge(clk) THEN --or falling_edge(clk)
new_output <= output;
END IF;
END PROCESS;
END architecture;
</syntaxhighlight>
;Dica: Se ao discrever uma FSM, faltar algum estado, o Quartus dará erro durante a compilação.  Para resolver temporariamente isso pode se usar antes de encerrar o case
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
WHEN others =>
[rótulo:] LOOP
nx_state <= <initial_state>;
            afirmação_sequencial;
            afirmação_sequencial;
            ...
          END LOOP [rótulo];
</syntaxhighlight>
</syntaxhighlight>


:* Usando o template acima descreva em VHDL a FSM indicada na Figura 11.1.
:* Faça a simulação da FSM com Modelsim utilizando um testbench em VHDL que faça a FSM seguir os estados
<center>
<math> RST \to A \xrightarrow{\text{x=0}}  A \xrightarrow{\text{x=1}} A \xrightarrow{\text{x=2}} B \xrightarrow{\text{x=2}} B \xrightarrow{\text{x=0}} C \xrightarrow{\text{x=0}} C \xrightarrow{\text{x=2}} C \xrightarrow{\text{x=1}} A \xrightarrow{\text{x=2}} B \xrightarrow{\text{x=1}} A </math>
</center>
:: Ver pag. 277 a 280 de <ref name="PEDRONI2010b"/>
:: Note que o uso da atribuição manual do '''enum_encoding''' pode faz com que o compilador do Quartus não  reconheça a FSM, mas use logica regular para representar o sistema.


;DESAFIO:
*Propor uma maquina de estados finita para controlar uma máquina de Lavar Roupas.
{{fig|4.2|Discussão da FSM da Máquina de Lavar Roupas na turma 2024.1 de ELD2 |FSM_LavaRoupas.jpg|1200 px|}}


;Encontro 29  (26 jul.)
*Instrução '''WHILE-LOOP''':
* Implementação em VHDL da FSM de máquina de Lavar Roupas
<syntaxhighlight lang=vhdl>
* Simulação em ModelSim da FSM de máquina de Lavar Roupas
[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>


;Encontro 30 (30 jul.)
*Instrução '''CASE''' 
* Avaliação A1
<syntaxhighlight lang=vhdl>
 
[rótulo opcional:] CASE expressão IS
 
                  WHEN valor =>                            -- valor único
====ATUAL====
                    afirmação_sequencial;                          
;Encontro 31 (2 ago.)
                    afirmação_sequencial;                           
* Modelagem de FSM com Diagrama de Estados e ASM (''Algorithmic State Machine'')
                    ...
* Diferença entre saída Moore e saída Mealy
                  WHEN valor1 | valor2 | ... | valorN  =>  -- lista de valores
* Modelagem de um controlador de memória com modo de leitura '''BURST'''.
                    afirmação_sequencial;                           
* Simulação do controlador de memória.
                    afirmação_sequencial;                           
{{fig|4.3|Simulação do controlador de memoria - diferença entre a saída Moore e saída Mealy|FSM_Moore_Mealy_SIM.png|1200 px|}}
                    ...
 
                  WHEN valor1 TO valor2 =>                  -- faixa de valores
{{fig|4.4|Simulação de escritas, leituras simples e leitura em burst no controlador de memoria |FSM_Mem_SIM.png|1200 px|}}
                    afirmação_sequencial;                           
 
                    afirmação_sequencial;
{{collapse bottom}}
                    ...
 
                  WHEN OTHERS  =>                          -- para evitar latches
==Avaliações==
                    afirmação_sequencial;                           
Durante o semestre serão realizadas 4 avaliações. As avaliações devem  ser enviadas pela plataforma Moodle com os arquivos solicitados.
                    afirmação_sequencial;
;Data das avaliações:
                    ...
*A1 - :
          END CASE;
*A2 - :
</syntaxhighlight>
*A3 - :
*A4 - :
*R - Recuperação de A1 a A4 :
*[[Folha de consulta de VHDL]]


== Atividade relâmpago (AR) ==
;Exemplos:
As atividades relâmpago devem ser entregues no Moodle da disciplina. A não entrega dessas atividades não gera nenhum desconto, apenas geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN.
* Leading Zeros (LOOP com EXIT) (Ex 6.5) - Esse circuito deve determinar quantos zeros tem em um vetor de entrada '''Data''' 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.


===AR1 - Conhecendo os dispositivos lógicos programáveis===
<syntaxhighlight lang=vhdl>
;Atividade:
entity leading_zeros is
Para esse desafio, no PASSO 3 da AE1, selecione o dispositivo EP4CE6E22C7 da família Cyclone IV E.
generic (N : natural := 8);
port
( ________ : in std_logic_vector(0 to N-1);
count : out integer range 0 to N
);
end entity;


Utilizando o circuito que realiza o cálculo da distância de Hamming entre dois sinais, procure melhorar o processo de compilação de modo que consiga reduzir ao máximo o tempo de propagação entre entrada e saída.
architecture ____ of leading_zeros is


*Insira restrições de atraso máximo para o compilador utilizando o Synopsys Design Constraints File
begin
*Modifique a técnica utilizada pelo Quartus na otimização em em Optimization Technique por default está selecionado [x] Balanced (Normal flow) .
process (data)
:*selecione uma das opções de [x] Performance para "procurar" reduzir o tempo de propagação e/ou aumentar a frequência máxima do sistema.
variable count : integer ____ 0 to N
:*selecione uma das opções de [x] Power para "procurar" reduzir a potência utilizados no sistema.
begin
:*selecione [x] Area para "procurar" reduzir o número de elementos lógicos utilizados no sistema.
count := 0;
*Altere a semente iniciaal em Fitter Initial Placement Seed.
for i ___ data'range ____
 
case data(i) is
;Entregas:
when '0' => count := count + 1;
*Envie o QAR com o projeto compilado e configurado com menor tempo de propagação entre entrada e saída que você conseguiu.
when _____ => exit;
*Envie a captura da imagem mostrando o relatório com este tempo.
end  ___
*Envie no texto online os seguintes dados:
end ____
:1) Optimization Technique usada
zeros <= count;
:2) Fitter Initial Placement Seed usada
end process;
:3) Paramentros usados no  Synopsys Design Constraints File
end _______;
:4) O caminho crítico (aquele que tem o maior tempo de propagação) e o tempo obtido.
</syntaxhighlight>
{{fig|5.15|Simulação do leading_zeros| SIM_LZ.png| 800 px | }}
 
* Contador de zeros (LOOP com NEXT ou apenas LOOP)  - Esse circuito deve determinar quantos zeros tem em um vetor de entrada '''Data'''.
:*Fazer a síntese do circuito; fazer simulação no Modelsim; analisar a forma como o compilador implementou o incrementador.
{{fig|5.16|Simulação do counting_zeros| SIM_CZ.png| 800 px | }}


;Bonificação na A1:
*Ver pag. 161 a 164 de <ref name="PEDRONI2010b"/>
*0,5 - para o(a) estudante que obtiver o menor tempo de propagação para o caminho crítico
*0,3 - para o(a) estudante que obtiver o segundo menor tempo de propagação para o caminho crítico
*0,2 - para o(a) estudante que obtiver o terceiro menor tempo de propagação para o caminho crítico


===AR2 - Desafio: contador bidirecional===
;Encontro 14 (6 mai.):
; Atividade:
*Implemente o contador de sequencia arbitraria (implementado com when else) (ver Listing 8.11 - Arbitrar-sequence counter).
Implementar um contador bidirecional entre MIN e MAX. Uma entrada DIR indica a direção da contagem. Considere DIR = 0 (para contagem crescente) e DIR = 1 (para contagem decrescente). Avaliar a frequencia máxima (Fmax) em que o circuito funcionará utilizando o '''dispositivo EP4CE10F17A7'''.
*Implemente o contador com opções de clear sincrono, load, e parada (ver Listing 8.13 - Featured binary counter).
*Versão 1: Com underflow no valor mínimo (MIN) e overflow no máximo (MAX).
*Implemente o contador de modulo m (onde m é uma entrada) (ver Listing 8.15 e 8.16 - Programmable mod-m counter).
*Versão 2: Com parada no valor mínimo (MIN), se decrescente e também no máximo (MAX) se crescente.


;Entregas:
;Encontro 15 (8 mai.):
* Para realizar a simulação e análise de tempo use MIN = 2 e MAX = 13.
* Projetar um divisor de clock que dado um clock de entrada de fclk Hz, produza na saída um sinal de clock de f/N onde N é um número inteiro ('''div_clk''')
* Envie o QAR com o projeto compilado e configurado com o '''maior valor de Fmax''' que você conseguiu.
<syntaxhighlight lang=vhdl>
* Envie a captura da imagem mostrando o relatório com essa frequência.
entity div_clk  is
* Envie a tela da simulação que mostra que o contador funciona (faça contar de 0 até MAX, e também decrementar até o MIN)
  port(
* Envie no texto online os seguintes dados:
    clk:      in std_logic;
:1) Qual versão foi implentada (v1 ou v2)
    reset:    in std_logic;
:2) O maior valor de Fmax obtido
clk_1ms:  out std_logic;
clk_10sec: out std_logic;
clk_1sec:  out std_logic
  );
end entity;
</syntaxhighlight>
:* Utilize esse circuito para obter um clock de 1 Hz (1 sec) '''clk_1sec''' a partir do sinal de 50MHz existente no kit DE2-115.
 
;Para o próximo encontro:
*Completar o projeto do divisor de clock, acrescentando:
:*Implemente uma segunda saída para um clock de 1kHz (1 ms) '''clk_1ms'''
:*Implemente uma terceira saída para um clock de 0,1 Hz (10 sec) '''clk_10sec'''
:* Configure o circuito no kit DE2-115 dispositivo '''EP4CE115F29C7''', usando 1 led para sinalizar cada um desses clocks gerados.
::ver [[Preparando para gravar o circuito lógico no FPGA]] e [[Interfaces de entrada e saída da DE2-115]]
<center>
{| class="wikitable" style="text-align:center;"
|- style="font-weight:bold; background-color:#c0c0c0;"
! porta
! pino
! nome do sinal no kit
|-
| clk || Y2 || CLOCK_50
|-
| reset || AB28 || SW[0]
|-
| clk_1sec || F17 || LEDG[8]
|-
| clk_10sec || E21 || LEDG[0]
|-
| clk_1ms || G19 || LEDR[0]
|}
</center>
:* No laboratório siga os passos: [https://wiki.sj.ifsc.edu.br/index.php/Preparando_para_gravar_o_circuito_l%C3%B3gico_no_FPGA#Programando_o_FPGA_na_m%C3%A1quina_local_com_o_c%C3%B3digo_em_nuvem Programando o FPGA na máquina local com o código em nuvem]


;Bonificação na A1:
*Preparar o código dos seguintes circuitos:
*1,0 - para  o(a) primeiro estudante que enviar o contador funcionando (versão 1 ou 2)
:*Contador de segundos e minutos com clock derivado (ver Listing 9.5)
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 1)
:*Contador de segundos e minutos síncrono (ver Listing 9.6)
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 2)


;Dicas:
;Encontro 16 (13 mai.):
* [[Restringir a frequencia máxima de clock no Quartus II]]
*Fazer a compilação completa, simular e fazer o timing analysis dos seguintes circuitos:
* [[Como obter o Fmax do projeto no Quartus]]
:*Contador de segundos e minutos com clock derivado (ver Listing 9.5)
{{fig|3.17|Contador de segundos e minutos - clock derivado| contaSSMMclk.png| 600 px |  <ref name="CHU2006"/> }}
 
:*Contador de segundos e minutos síncrono (ver Listing 9.6)
{{fig|3.18|Contador de segundos e minutos - clock síncrono | contaSSMMsync.png| 600 px |  <ref name="CHU2006"/>}}


===AR3 - Desafio: contador bcd===
; Atividade:
Implementar um contador BCD de 00 a 99, com parada em qualquer valor MAX_DU. Se os parâmetros dos contador D = 5 e U = 9, isso implica em contar de 00 até 59 e ficar parado neste valor. A atingir o valor final MAX_DU, uma saída adicional OPA deve ser ativada. Avaliar a frequencia máxima (Fmax) em que o circuito funcionará utilizando o '''dispositivo EP4CE10F17A7'''.


*Versão 1: O contador '''crescente''' deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com parada em MAX_DU.
;Encontro 17(15 mai.):
*Versão 2: O contador '''crescente''' deve fazer a contagem em binário, e incrementar 6 nos bits da unidade sempre que passar de 9(1001) para 10 (1010), com parada em MAX_DU.
Comparar o desempenho Fmax, número de elementos lógicos, número de registradores, número de pinos dos seguintes contadores, considerando uma saída de N_bits.
*Versão 3: O contador '''decrescente''' deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com início em MAX_DU e parada em 00.
*Contador binario sequencial
  b_next <= b_reg+1;


;Entregas:
*Contador Gray (só troca um bit por vez) [https://drive.google.com/file/d/1GTkw-JvBRljvfJJNOA_cGmZzWkKDhp8M/view?usp=drive_link L9.7 de <ref name="CHU2006"/>]
* Na simulação e na análise considere a contagem de 00 a 23, definindo os parâmetros D = 2 e U = 3.
:: ver [[Código Gray]]
* Envie o QAR com o projeto compilado e configurado com o '''maior valor de Fmax''' que você conseguiu.
  b <= g_reg xor ('0' & b(WIDTH-1 downto 1));
* Envie a captura da imagem mostrando o relatório com essa frequência.
  b1 <= b+1;
* Envie a tela da simulação que mostra que o contador funciona fazendo ele contar de 0 até 23 (ou 23 até 0), deixe o período a mais no final para mostrar que o contador parou.
  g_next <= b1 xor ('0' & b1(WIDTH-1 downto 1));
* Envie no texto online os seguintes dados:
:1) Qual versão foi implentada (v1, v2 ou v3).
:2) O maior valor de Fmax obtido.
:3) Qual o número de elementos lógicos utilizados no projeto.


;Bonificação na A1:
*Contador em anel (desloca um padrão inicial) [https://drive.google.com/file/d/1KEswDlpNqbgROcsr4MMh4BCr2tmDB3-k/view?usp=drive_link L9.8 e 9.9 de  <ref name="CHU2006"/>]
*1,0 - para  o(a) primeiro estudante que enviar o contador funcionando (versão 1, 2 ou 3)
  r_next <= r_reg(0) & r_reg(WIDTH-1 downto 1);
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax (versão 1)
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 2)
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 3)


== Atividade extra-classe (AE) ==
*Contador Johnson (uso de um inversor na realimentação do contador em anel)
A média ponderada das atividades extra-classe será considerada no cálculo do conceito final da UCA entrega das mesmas será feita pelo Moodle, e cada dia de atraso irá descontar 0,2 na nota da atividade. Muitas dessas atividades também geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN.  Para os BÔNUS só serão considerados projetos entregues no prazo.
  r_next <= (not r_reg(0)) & r_reg(WIDTH-1 downto 1);
*Contador LFSR (Linear Feedback Shift Register) [https://drive.google.com/file/d/1wjypyztGMxiUxsPNwZ8j-PQkTMwoyFu3/view?usp=drive_link L9.10 e 9.11 de  <ref name="CHU2006"/>]
  fb <= r_reg(1) xor r_reg(0);
  r_next <= fb & r_reg(3 downto 1);
:*
;Para o próximo encontro
* Ver como se pode implementar um contador [https://en.wikipedia.org/wiki/Linear-feedback_shift_register LFSR] de n bits.   
* Consultar [https://users.ece.cmu.edu/~koopman/lfsr/] ou a página 5 de [https://docs.amd.com/v/u/en-US/xapp052] para obter os termos que são usados na realimentação.


===AE1 - Conhecendo os dispositivos lógicos programáveis===
;Encontro 18(20 mai.):
{{collapse top | expand=true | bg=lightyellow | AE1 -  Conhecendo os dispositivos lógicos programáveis}}
*'''Circuito de PWM''' (''Pulse Width Modulation'' - Modulação por largura de pulso) [https://drive.google.com/file/d/1FLvKLrSAZs9HQkz-QxkB3rsDHyGryf1-/view?usp=drive_link L9.14 de <ref name="CHU2006"/>].
;Objetivos:
:*Em algumas aplicações ao invés de usar diretamente a contagem, se usa o estado do contador para geram sinais de saída. Um exemplo é um circuito de modulação por largura de pulso (PWM), que gera um pulso de saída com um ciclo de trabalho ajustável.
*Conhecer o Quartus Prime e as características dos dispositivos lógicos programáveis
:*Por exemplo, em um circuito PWM que tem 16 passos, o ciclo de trabalho pode ser ajustado em incrementos de 1/16, ou seja, o ciclo de trabalho pode ser 1/16, 2/16, 3/16, ..., até 16/16. Este circuito pode ser implementado por um contador mod-16 com um circuito de saída especial, que define o valor da saída em alto de acordo com o valor da contagem. O período dos pulsos de saída neste caso sempre será de 16 vezes o período do relógio. 
*Analisar os tempos de propagação em um circuito combinacional
*Alterar configurações do compilador
*Fazer a simulação funcional e temporal de um circuito combinacional.


;Atividades:
:*Note que uma expressão booleana adicional, w="0000", é incluída para acomodar a condição especial.
*'''PASSO 1:''' Realize a atividade descrita em [[Conhecendo os dispositivos lógicos programáveis - QUARTUS PRIME]]
<syntaxhighlight lang=vhdl>
:*Ao escolher a família de FPGAS, escolha inicialmente um dispositivo da família '''Max II'''. Anote o código desse dispositivo.
  buf_next <= '1' when (r_reg<unsigned(w)) or (w="0000") else '0';
:*Capture as telas solicitadas e depois utilize-as no relatório da atividade.
</syntaxhighlight>
:*Anote o tempo utilizado para cada uma das etapas do processo de compilação.
{{fig|5.X|RTL do circuito de PWM| PWM_RTL.png| 600 px | }}
:*Anote o número de elementos lógicos utilizados e o número de pinos utilizados, bem com o percentual em relação ao número total do dispositivo.
Na simulação abaixo, um clock de 50 ps foi utilizado, e o '''valor da entrada w''' foi definida como (3, 8, 0, 1, 15) a cada 1600 ps.  Note que a largura do pulso da '''saída pwm_pulse''' está de acordo com aquela entrada.
:*Anote algum erro ('''Error''') ou alertas ('''Warnings''') que o Quartus II indicar no painel de mensagens '''[Messages]'''
{{fig|5.X|Simulação do circuito de PWM| PWM_SIM.png| 1000 px | }}
:*Ao final salve o projeto em um arquivo QAR (sugestão PJ1.QAR)


*'''PASSO 2''': Repita a atividade descrita em [[Conhecendo os dispositivos lógicos programáveis - QUARTUS PRIME]], trocando a família e dispositivo a ser usado na implementação.  Escolha nesta vez um dispositivos da família '''Cyclone IV E'''  ou  '''Stratix II GX'''. Anote o código desse dispositivo.
*Implementar um contador decrescente N até 0, com N ≠ 2^Mbits (5, 10)
:*Observe as mudanças que ocorrem tanto no tipo de Elemento Lógico disponível, no Chip Planner, no Pin Planner, e no circuito dos pinos de I/O. Note que estes FPGAs também apresenta novos componentes, tais como: Memória, Multiplicadores, DSP, PLL, DLL, etc. Verifique se consegue encontra-los no leiaute mostrado no Chip Planner,  e documente aqueles que encontrar.
:*Com underflow no valor mínimo
:*Compare os resultados obtidos nos procedimentos do PASSO 1 e PASSO 2.
{{fig|5.13|Simulação do contador decrescente 5 a 0| Counter_5_0_SIM.png| 800 px | }}


*'''PASSO 3''': Realize o procedimento descrito em [[Medição de tempos de propagação em circuitos combinacionais - Quartus Prime]]
*Implementar um contador decrescente com parada no valor mínimo
:*Ao escolher a família de FPGAS, escolha um dispositivo FPGA da família '''Cyclone IV E'''. Anote o código desse dispositivo.
{{fig|5.14|Simulação do contador decrescente 5 a 0 com parada| Counter_5_0_SIM_stop.png| 800 px | }}
:*Capture as telas mostradas no roteiro e depois utilize-as no relatório da atividade.
 
:*Anote o máximo tempo de propagação entre entrada e saída.
*Implementar um contador bidirecional entre MIN e MAX.  Uma entrada DIR indica a direção da contagem. Considere DIR = 0 (crescente) e  DIR = 1 (decrescente).
:*Anote o número de elementos lógicos utilizados e o número de pinos utilizados, bem com o percentual em relação ao número total do dispositivo.
:*'''Versão 1:''' Com underflow no valor mínimo (MIN) e overflow no máximo (MAX).
:*Experimente modificar as configurações do compilador, conforme mostrado em '''Configurando o compilador'''Se desejar mude a semente inicial trocando o valor de '''[Seed: 1]'''
:*'''Versão 2:''' Com parada no valor mínimo (MIN), se decrescente e também no máximo (MAX) se crescente.
:*Experimente inserir diferentes restrições de atraso máximo para o compilador, e analise o resultado obtido.
;Encontro 19 (22 mai.):
:*Anote algum erro ('''Error''') ou alertas ('''Warnings''') que o Quartus II indicar no painel de mensagens '''[Messages]'''
*Instrução '''IF GENERATE'''
:*Ao final salve o projeto em um arquivo QAR (sugestão PJ2.QAR)
 
 
<syntaxhighlight lang=vhdl>
*'''PASSO 4''': Realize a simulação funcional de um dos projetos '''CI74161''' ou do '''cálculo da distância de Hamming'''
<generate_label>:  
:*Capture as telas que mostram o circuito funcionando e depois utilize-as no relatório da atividade.
if <condition> generate
 
-- Concurrent Statement(s)
;Entregas:
end generate;
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar cada um dos projetos.
</syntaxhighlight>
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa.  O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão.  A descrição dos procedimentos feita na página wiki não precisa incluída no relatório.
 
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida.
Essa instrução é utilizada para a geração condicional de código durante a elaboração. Com isso, partes do projeto são sintetizadas e outras não, dependendo de certas condições ou parâmetros definidos no projeto. Como ela faz parte do grupo de instruções concorrentes, ela não pode ser utilizada dentro de PROCESS, FUNCTION ou PROCEDURE.
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
 
{{collapse bottom}}
Para exemplificar, consideramos a situação em que um contador crescente (UP)  OU um contador decrescente (DOWN) devem serm utilizados, mas o contador nunca será aplicado nas duas direções de contagemNeste caso, é possível estabelecer um parâmetro  '''GENERIC''', que definirá se a contagem é UP ou DOWN.  Analise o código a seguir escrito em segmento único e usando variável:
 
<syntaxhighlight lang=vhdl>
===AE2 -  Estudando uma FIFO===
entity contador_up_down_if_generate is
{{collapse top | expand=true | bg=lightyellow | AE2 -  Estudando uma FIFO}}
generic
;Objetivos:
(
*Conhecer um file register, controlador de FIFO e uma FIFO completa
MIN    : natural := 3;
*Analisar o desempenho (Fmax) e área ocupada pelo circuito usando diferentes versões de implementação
MAX    : natural := 21;
*Construir uma FIFO usando como componentes um file register e um controlador de FIFO
UPDOWN  : natural := 0          -- 0 => up; 1 => down
*Fazer a simulação funcional dos componentes individuais e da FIFO
);
 
port
;Atividades:
(
*'''PASSO 1 -''' Código do Register File
clk, rst  : in std_logic;
:*Use o código disponibilizado no Moodle
cnt_out    : out integer range MIN to MAX  -- Aqui deveria ser usado std_logic_vector
);
end entity;
</syntaxhighlight>
 
<syntaxhighlight lang=vhdl>
architecture ifsc_v1 of contador_up_down_if_generate is
begin
L1: if UPDOWN = 0 generate
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MIN;
elsif (rising_edge(clk)) then
if cnt = MAX then
cnt := MIN;
else
cnt := cnt + 1;
end if;
end if;
cnt_out <= cnt;
end process;
end generate;
L2: if UPDOWN = 1 generate
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MAX;
elsif (rising_edge(clk)) then
if cnt = MIN then
cnt := MAX;
else
cnt := cnt - 1;
end if;
end if;
cnt_out <= cnt;
end process;
end generate;
end architecture;
</syntaxhighlight>
 
Agora analise o mesmo contador descrito em dois segmentos, parte sequencial e parte de logica de próximo estado:
 
<syntaxhighlight lang=vhdl>
architecture ifsc_v2 of contador_up_down_if_generate is
    signal reg_cnt, next_cnt : integer range MIN to MAX;
begin
    -- Contagem crescente
    L1: if UPDOWN = 0 generate
        -- Segmento sequencial
        process (clk, rst)
        begin
            if rst = '1' then
                reg_cnt <= MIN;
            elsif rising_edge(clk) then
                reg_cnt <= next_cnt;
            end if;
        end process;
        -- Segmento de próximo estado
        next_cnt <= MIN when reg_cnt = MAX else reg_cnt + 1;
    end generate;
 
    -- Contagem decrescente
    L2: if UPDOWN = 1 generate
        -- Segmento sequencial
        process (clk, rst)
        begin
            if rst = '1' then
                reg_cnt <= MAX;
            elsif rising_edge(clk) then
                reg_cnt <= next_cnt;
            end if;
        end process;
        -- Segmento de próximo estado
        next_cnt <= MAX when reg_cnt = MIN else reg_cnt - 1;
    end generate;
    -- Código de saída
    cnt_out <= reg_cnt;
end architecture;
</syntaxhighlight>
 
Se o parâmetro '''UPDOWN''' for instanciado com 0, teremos um contador crescente.  Caso seja instanciado com 1, o contador será decrescente.  Veja a simulação nos dois casos.
{{fig|5.20|Simulação do contador UPDOWN com 0 | MODELSIM_countUP.png | 800 px |}}
{{fig|5.21|Simulação do contador UPDOWN com 1 | MODELSIM_countDOWN.png | 800 px |}}
 
*Uso de duas architecture para obter a mesma opção do '''IF GENERATE'''
<syntaxhighlight lang=vhdl>
entity contador_up_down_two_arch is
generic
(
MIN : natural := 3;
MAX : natural := 21
);
port
(
clk, rst    : in std_logic;
count_out  : out integer range MIN to MAX
);
end entity;
 
architecture arch_up of contador_up_down_two_arch is
begin
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MIN;
elsif (rising_edge(clk)) then
if cnt = MAX then
cnt := MIN;
else
cnt := cnt + 1;
end if;
end if;
count_out <= cnt;
end process;
end architecture;
 
architecture arch_down of contador_up_down_two_arch is
begin
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MAX;
elsif (rising_edge(clk)) then
if cnt = MIN then
cnt := MAX;
else
cnt := cnt - 1;
end if;
end if;
count_out <= cnt;
end process;
end architecture;
 
configuration ifsc_cfg of contador_up_down_2arch is
-- for arch_up end for;
for arch_down end for;
end configuration;
</syntaxhighlight>
 
*Uso de uma porta de entrada UPDOWN fixada em '0' ou '1' para obter a mesma opção do '''IF GENERATE'''
 
<syntaxhighlight lang=vhdl>
entity contador_up_down_pin is
generic
(
MIN : natural := 3;
MAX : natural := 21
);
port
(
clk, rst   : in std_logic;
UPDOWN : natural := 1; -- 0 => up; 1 => down
count_out  : out integer range MIN to MAX
);
end entity;
 
architecture ifsc_v1 of contador_up_down_pin is
signal cnt_down, cnt_up  : integer range MIN to MAX;
begin
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MIN;
elsif (rising_edge(clk)) then
if cnt = MAX then
cnt := MIN;
else
cnt := cnt + 1;
end if;
end if;
cnt_up <= cnt;
end process;
 
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MAX;
elsif (rising_edge(clk)) then
if cnt = MIN then
cnt := MAX;
else
cnt := cnt - 1;
end if;
end if;
cnt_down <= cnt;
end process;
count_out <= cnt_up when UPDOWN = 1 else cnt_down;
end architecture;
</syntaxhighlight>
 
 
;Encontro 20 (27 mai.):
*Uso de componentes e instanciação de componentes.
<blockquote style="background: lightblue; border: 3px solid black; padding: 1em;">
Nesta parte da materia, o aluno deverá aprender a perguntar para uma ferramente de IA (e.g. ChatGPT) sobre um conteúdo específico formulando perguntas que conduzam a resposta e detalhamento desejado.  De acordo com as respostas as perguntas precisam ser adaptadas.  As respostas precisam ser avaliadas, pois podem conter erros graves.  Exemplo de ordem de perguntas:
:1) Como é feita a instanciação de componentes em VHDL? 
:2) Como devem ser os arquivos da entidade e do top level?
:3) Quais tipos de instanciação existem?  Além dessa instanciação nominal, também  existe a posicional, podes explicar e exemplificar os dois casos?
:4) O que devo fazer se não for utilizada uma porta de entrada ou de saída na instanciação de um componente?
</blockquote>
 
{{collapse top | expand=true | Resposta do ChatGPT}}
 
A instanciação de componentes em VHDL é o processo de incluir e conectar componentes em um design hierárquico. Isso permite que você reutilize módulos já implementados em diferentes partes do projeto. O processo de instanciação segue algumas etapas, conforme descrito abaixo:
 
; Declaração do componente:
Antes de usar um componente em uma arquitetura, ele precisa ser declarado no escopo da arquitetura (a menos que você esteja usando bibliotecas com pacotes, onde a declaração pode ser omitida). A declaração define os sinais de entrada e saída do componente.
 
component_declaration ::= 
    component identifier [ is ] 
        [ generic_clause ] 
        [ port_clause ] 
    end component [ identifier ] ;
 
Exemplo de declaração do componente:
 
<syntaxhighlight lang=vhdl>
component MeuComponente is
    generic (
        WIDTH : natural := 4
    )
    port (
        clk  : in  std_logic;
        reset : in  std_logic;
        data  : in  std_logic_vector(7 downto 0);
        valid : out std_logic
    );
end component;
</syntaxhighlight>
 
;Instanciação do componente:
Após declarar o componente, ele pode ser instanciado dentro do corpo da arquitetura. Na instanciação, você define um "rótulo" (um nome para a instância) e conecta as portas do componente aos sinais locais do módulo que o utiliza. Existem duas formas principais de conectar as portas durante a instanciação:
 
Conexão posicional: As portas são conectadas pela ordem em que aparecem no port map. Deve-se garantir que a ordem dos sinais corresponda à ordem definida no componente.
 
Exemplo:
 
<syntaxhighlight lang=vhdl>
Instancia2: MeuComponente
    generic map (
        8
    )
    port map (
        clk_signal,
        reset_signal,
        input_data,
        output_valid
    );
</syntaxhighlight>
 
Conexão nomeada: As portas são conectadas explicitamente pelo nome, o que é mais claro e menos propenso a erros. Este é o método preferido, especialmente em designs complexos.
<syntaxhighlight lang=vhdl>
Instancia1: MeuComponente
    generic map (
        WIDTH => 8
    )
    port map (
        clk  => clk_signal,
        reset => reset_signal,
        data  => input_data,
        valid => output_valid
    );
</syntaxhighlight>
No exemplo acima
*'''Instancia1''' é o rótulo da instância.
*'''clk, reset, data,''' e '''valid''' são os nomes das portas do componente.
*'''clk_signal, reset_signal, input_data''', e '''output_valid''' são os sinais do módulo que está utilizando o componente.
 
Em VHDL, os arquivos da entidade (componente) e do top level (nível superior do design) seguem uma estrutura organizada para garantir a modularidade, reutilização de código e facilidade de manutenção. Abaixo está uma explicação de como estruturar esses arquivos corretamente.
 
;Arquivo da Entidade (Componente):
Um arquivo que define uma entidade (componente) deve conter:
*A declaração da entidade, que define as entradas e saídas do módulo.
*A arquitetura, que contém a lógica do componente (ou uma descrição de como ele é implementado).
Exemplo de Arquivo para o Componente:
<syntaxhighlight lang=vhdl>
-- Arquivo: MeuComponente.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
-- Declaração da entidade
entity MeuComponente is
    port (
        clk  : in  std_logic;
        reset : in  std_logic;
        data  : in  std_logic_vector(7 downto 0);
        valid : out std_logic
    );
end MeuComponente;
 
-- Declaração da arquitetura
architecture Behavioral of MeuComponente is
begin
    -- Implementação da lógica do componente
    process(clk, reset)
    begin
        if reset = '1' then
            valid <= '0';
        elsif rising_edge(clk) then
            if data = "11111111" then
                valid <= '1';
            else
                valid <= '0';
            end if;
        end if;
    end process;
end Behavioral;
</syntaxhighlight>
Neste exemplo:
*Entidade: Define as portas (clk, reset, data, valid).
*Arquitetura: Implementa a lógica funcional do componente.
;Arquivo do Top Level:
O arquivo do Top Level é responsável por integrar e conectar os componentes em um design hierárquico. Ele também define as entradas e saídas globais do sistema e instancia os componentes (como o MeuComponente no exemplo).
 
Exemplo de Arquivo Top Level:
<syntaxhighlight lang=vhdl>
-- Arquivo: TopLevel.vhd
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
-- Declaração da entidade do Top Level
entity TopLevel is
    port (
        clk  : in  std_logic;
        reset : in  std_logic;
        data  : in  std_logic_vector(7 downto 0);
        valid : out std_logic
    );
end TopLevel;
 
-- Declaração da arquitetura do Top Level
architecture Structural of TopLevel is
    -- Sinais internos para conexão
    signal clk_signal  : std_logic;
    signal reset_signal : std_logic;
    signal input_data  : std_logic_vector(7 downto 0);
    signal output_valid : std_logic;
 
    -- Declaração do componente
    component MeuComponente is
        port (
            clk  : in  std_logic;
            reset : in  std_logic;
            data  : in  std_logic_vector(7 downto 0);
            valid : out std_logic
        );
    end component;
 
begin
    -- Conectando sinais externos aos sinais internos
    clk_signal  <= clk;
    reset_signal <= reset;
    input_data  <= data;
 
    -- Instanciação do componente
    Instancia1: MeuComponente
        port map (
            clk  => clk_signal,
            reset => reset_signal,
            data  => input_data,
            valid => output_valid
        );
 
    -- Conectando o sinal interno à saída global
    valid <= output_valid;
end Structural;
</syntaxhighlight>
Neste exemplo:
*O Top Level possui sua própria entidade e arquitetura.
*Ele instancia o componente MeuComponente e conecta os sinais externos (entradas e saídas globais) aos sinais internos que se conectam ao componente.
;Organização dos Arquivos:
Nomeação dos Arquivos:
*O nome do arquivo deve corresponder ao nome da entidade definida dentro dele.
*Por exemplo:
:*Para a entidade MeuComponente, o arquivo deve ser MeuComponente.vhd.
:*Para a entidade TopLevel, o arquivo deve ser TopLevel.vhd.
Separação de Arquivos:
*Cada entidade e arquitetura deve estar em um arquivo separado.
*Isso facilita a reutilização e a organização, especialmente em projetos maiores.
Hierarquia:
*O Top Level deve ser o ponto de entrada do design. Ele referencia (ou instancia) os componentes.
;Como Compilar e Simular:
Para que os arquivos funcionem juntos, siga estas etapas:
 
Compilação:
*Compile primeiro os arquivos dos componentes, como MeuComponente.vhd.
*Depois, compile o arquivo do Top Level, que depende dos componentes.
Simulação:
*Simule o arquivo do Top Level, pois ele integra todos os componentes.
*Use um banco de testes (testbench) conectado ao Top Level para verificar o comportamento geral.
Ferramentas de Desenvolvimento:
*Use ferramentas como ModelSim, Quartus, Xilinx Vivado ou GHDL para compilar, simular e sintetizar os arquivos.
 
Quando uma porta de entrada ou saída de um componente não é utilizada durante a instanciação em VHDL, você deve explicitamente informar isso no momento da conexão com o port map. Isso garante que o design seja claro e sem erros de compilação, já que todas as portas devem ser conectadas (mesmo que não sejam usadas).
 
A forma de lidar com isso depende se a porta é de entrada ou saída:
;Para uma Porta de Entrada Não Utilizada
As portas de entrada devem receber um valor, mesmo que não sejam usadas na lógica. Nesse caso, você pode:
Você pode conectar a porta a um literal (como '0', '1' ou "000...").
 
Exemplo:
 
<syntaxhighlight lang=vhdl>
Instancia1: MeuComponente
    port map (
        clk  => clk,
        reset => reset,
        data  => (others => '0'), -- Porta de entrada não utilizada
        valid => valid_signal
    );
</syntaxhighlight>
 
No exemplo acima, a entrada data foi conectada a (others => '0'), indicando que todos os bits do vetor serão definidos como 0.
 
;Para uma Porta de Saída Não Utilizada:
As portas de saída não precisam ser conectadas diretamente a nada, mas é necessário indicar explicitamente que você está ignorando a saída. Para isso, você pode usar a palavra-chave '''open'''.
 
Exemplo:
 
<syntaxhighlight lang=vhdl>
Instancia3: MeuComponente
    port map (
        clk  => clk,
        reset => reset,
        data  => data_signal,
        valid => open -- Porta de saída não utilizada
    );
</syntaxhighlight>
O '''open''' informa que a saída valid não será usada e evita que o compilador gere erros.
{{collapse bottom}}
Ao fazer as mesmas perguntas para a mesma IA, as respostas podem ser diferentes.  Por isso, todas respostas de IA deve passar por um processo de curadoria por humanos.
;Encontro 21 a 23 (29 mai. a 05 jun.): Timer de segundos, com mostrador SSD
*Utilize como componente o contador BCD 00-99 já foi construido em aula anterior ('''contaBCD.vhd'''). Será necessário acrescentar um sinal de enable ao contador, também assegure-se que seja possível configurar a contagem de 00 até NN.  Através do IF GENERATE disponibilize um contador que faça o overflow, e outro que pare ao chegar ao final da contagem. Também inclua uma entrada  ZERAR, e outra de CONTAR, que tem a função dada pelo nome.
*Utilize como componente o divisor de clock para gerar um sinal de enable para o contador a cada segundo ('''div_clk.vhd''').
*Projete um componente para converter de BCD para SSD - display de sete segmentos ('''bcd2ssd.vhd''').  Esse conversor deve ter uma entrada que permite escolher se o mostrador  é do tipo anodo comum ou catodo comum, utilizando a instrução IF GENERATE.  Para possibilitar mostrar ou não o zero, deve haver uma entrada que ao ser ativada fará com que o número zero não seja mostrada no mostrador.
*Crie um projeto top_level no qual existem 4 instancias. 2 instancias do componente '''bcd2ssd.vhd''' uma em cada saída do contaBCD.vhd, o qual deverá contar apenas de 00 a 59 e reiniciar a contagem.  Utilize o componente div_clk.vhd para habilitar o contaBCD.vhd.
*Faça a simulação de cada um dos componentes e simule o timer completo.
*Escolha um dos kits disponíveis no lab e implemente o projeto. Em seguida configure o circuito para ser implementado nos 2 mostradores (HEX0, HEX1).
:1) Verifique se o mostrador do seu kit é do tipo anodo comum ou catodo comum.
:2) Confira quais os clocks estão disponíveis no kit.
:3) Defina quais serão as chaves de controle do timer.  CONTAR, ZERAR, RESET
:4) A entrada que permite esconder o zero deve ser configurada de modo que a primeira instância mostre o número zero, enquanto a segunda instância ocultará o zero.
 
<syntaxhighlight lang=vhdl>
entity timer_seg is
    generic (DEZENA : natural :=5; UNIDADE : natural := 9; FCLK := 5); -- para simulaçao
port (
CLK50MHZ, RESET : in std_logic;
CONTAR      : std_logic;
ZERAR        : std_logic;
LED_SEG      : out std_logic;
SSD_DEZENA  : out std_logic_vector(6 downto 0);
SSD_UNIDADE  : out std_logic_vector(6 downto 0);
);
end entity;
 
architecture ifsc of top_level is
 
begin
 
end architecture;
</syntaxhighlight>
 
{{fig|5.17|RTL timer_sec | RTL_timer_sec.png| 800 px |}}
 
A seguir o resultado da simulação do '''timer_sec''' de segundos desde 00 até 59 segundos.  No próximo segundo é feito o overflow, retornando a 00.  O teste da entrada '''CONTAR''' é feito mantendo ela ativa inicialmente, e desativando-a entre 7,5 e 12,3 segundos, o que para a contagem. Para testar a entrada '''ZERAR''', ela é atividada no segundo 86,3, zerando o contador na próxima borda do clock. A contagem reinicia em 87 segundos quando o sinal ZERAR é desativado.  O sinal '''RESET''' é apenas usado no início da simulação para inicializar os registradores.
 
{{fig|5.18|Simulação do timer_sec | SIM_timer_sec.png| 800 px |}}
 
{{fig|5.19|Simulação do div_clk | SIM_div_clk.png| 800 px |}}
 
{{fig|5.20|Simulação do conta_bcd| SIM_conta_bcd.png| 800 px |}}
 
{{fig|5.21|Simulação do bcd2ssd (Catodo Comum)| SIM_bcd2ssdCC.png| 800 px |}}
 
{{fig|5.22|Simulação do bcd2ssd (Anodo Comum)| SIM_bcd2ssdAC.png| 800 px |}}
 
*Ver funcionamento do [[Display de 7 segmentos]]
 
-->
<!--
 
;Encontro 13  (5 abr.)
* 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'''
 
Esse somador pode ser implementado tanto com código sequencial como com código concorrente.  Note que no primeiro caso o bit de '''carry''' se definido como '''variable''' pode ser reaproveitado.  No segundo caso é necessário criar um vetor completo para conectar os '''carry_out''' de um estágio ao '''carry_in''' do próximo.
 
<syntaxhighlight lang=vhdl>
library ieee;
use ieee.std_logic_1164.all;
 
entity carry_ripple_adder is
generic (N : integer := 3);
port (
a, b : std_logic_vector (N-1 downto 0);
cin  : std_logic;
s    : out std_logic_vector (N-1 downto 0);
cout : out std_logic
);
end entity;
 
architecture estrutural_sequencial_v1 of carry_ripple_adder is
begin
-- Uso de um codigo sequencial para geracao de um circuito combinacional
process (a, b, cin) is
variable c : std_logic;
begin
c := cin;
for i in 0 to N-1 loop
s(i) <= a(i) xor b(i) xor c;
c := (a(i) and b(i)) or (a(i) and c) or (b(i) and c);
end loop;
cout <= c;
end process;
end architecture;
 
architecture estrutural_concorrente_v1 of carry_ripple_adder is
signal c : std_logic_vector(N downto 0);
begin
-- Uso de um codigo concorrente para geracao de um circuito combinacional
c(0) <= cin;
l1: for i in 0 to N-1 generate
s(i) <= a(i) xor b(i) xor c(i);
c(i+1) <= (a(i) and b(i)) or (a(i) and c(i)) or (b(i) and c(i));
end generate;
cout <= c(N);
end architecture;
</syntaxhighlight>
 
{{fig|5.17|RTL do carry_ripple_adder de 3 bits | RTL_carry_ripple_adder3.png| 800 px |}}
-->
<!--
;Encontro 17 (12 nov.):
* Uso de type para definir novos tipos de dados.  Exemplo de integer_vector
 
*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'''.
 
* Projetar um contador em BCD entre 0 e 99 ('''countBCD_DU.vhd'''), com entrada de clock, reset e saidas unidade(0 a 9) e dezena (0 a 9). Projete o contador para parar em qualquer valor de DU onde D é a dezena e U é a unidade.
 
:* versão 1 - contagem crescente.
{{fig|5.18|RTL do contador BCD 00 a 99 | RTL_countBCD00-99.png| 800 px |}}
{{fig|5.19|Simulação do contador BCD 00 a 99 | MODELSIM_countBCD00-99.png| 800 px |}}
 
;DESAFIO:
Implementar um contador BCD de 00 a 99, com parada em qualquer valor MAX_DU.  Onde se D = 5, U = 9, implica em contar de 000 até 59 e ficar parado neste valor.  A atingir o valor final MAX_DU, uma saída adicional OPA deve ser ativada.
*Versão 1: O contador crescente deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com parada em MAX_DU.
*Versão 2: O contador crescente deve fazer a contagem em binário, e incrementar 6 nos bits da unidade sempre que passar de 9(1001) para 10 (1010), com parada em MAX_DU.
*Versão 3: O contador decrescente deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com início em MAX_DU e parada em 00.
 
;Encontro 19 e 20 (19 e 21 nov.):
 
 
;Encontro 21 (26 nov.):
 
* Projetar um divisor de clock que dado um clock de entrada de f Hz, produza na saída um sinal de clock de f/N onde N é um número inteiro ('''div_clk_N''')
:* Utilize esse circuito para obter um clock de 1 Hz a partir do sinal de 50MHz existente no kit DE2-115.
:* Utilize um segundo circuito para obter um clock de 0,1 Hz
:* Teste o circuito no kit DE2-115.
 
 
;Encontro 22 (28 nov.):
 
 
;Encontro 24 e 25 (5 e 10 dez.)
*Implementação de um relógio HHMMSS usando os componentes desenvolvidos nas aulas anteriores.
*[https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE2_-_Laborat.C3.B3rio_de_programa.C3.A7.C3.A3o_de_FPGA_-_Rel.C3.B3gio_HHMMSS AE2 - Laboratório de programação de FPGA - Relógio HHMMSS]
*Análise da necessidade de utilizar um sinal de ENABLE para ativar os contadores de SS MM e HH no lugar de gerar o clock pelo circuito anterior.
 
;Encontro 26 (12 dez.)
* Testes finais do relógio HHMMSS (se todos alunos estiverem com simulações feitas e pinagem pronta).
* Implementação da função de LOAD para definir os valores iniciais da HH, MM e SS no relógio.
:*Sugestão utilizar 4 chaves para definir o valor em binário da unidade, outras 4 chaves para definir a dezena, e por último 1 chave para carregar a hora, 1 para o minuto e 1 para o segundo.  É fundamental que a chave stop esteja funcionando para permitir iniciar o relógio no momento exato.
:* Ajustar pelo [https://www.horariodebrasilia.org/ Horário de Brasilia]
 
;Encontro 27 e 28 (17 e 19 dez.)
 
* Registradores como armazenamento temporário
-->
{{collapse bottom}}
 
===Unidade 4 - Maquinas de Estado Finitas===
* 5 ENCONTROS
{{collapse top | expand=true | Unidade 4 - Maquinas de Estado Finitas}}
<!--
;Encontro 26  (12 jun.)
* O que é uma FSM - Finite State Machine
{{fig|4.1|Exemplo de diagrama de estados de uma FSM Fig4.1(a) e implementação em hardware da FSM Fig4.2(a)|Fig11_1_FSM.png|800 px|Figura 11.1 e 11.2 de <ref name="PEDRONI2010b"/>}}
* Modelo básico em VHDL de FSM
<syntaxhighlight lang=vhdl>
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
----------------------------------------------------------
ENTITY < entity_name > IS
PORT (
clk, rst : IN STD_LOGIC;
entradas : IN < data_type > ;
saidas : OUT < data_type >);
END entity;
----------------------------------------------------------
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 rising_edge(clk) THEN
-- apenas na borda do "clk" ocorre a mudança de estado da FSM
pr_state <= nx_state;
END IF;
END PROCESS;
------Logica Combinacional da FSM:------------
PROCESS (pr_state, entradas)
BEGIN
------Valores default das saidas------------
                saidas <= < valor > ;
CASE pr_state IS
WHEN A =>
-- é necessário um  WHEN para definir as "saidas" durante cada estado
-- e analisar as "entradas" para definir o próximo estado
saidas <= < valor > ;  -- apenas se diferente do valor default
IF (entradas = < valor >) THEN
nx_state <= B;
...
ELSE
nx_state <= A;
END IF;
WHEN B =>
saidas <= < valor > ; -- apenas se diferente do valor default
-- dependendo das "entradas", pode ser que hajam mais de um estados de destino
IF (entradas = < valor >) THEN
nx_state <= C;
ELSIF (entradas = < valor >) THEN
nx_state <= A;
ELSE
nx_state <= B;
END IF;
WHEN C =>
saidas <= < valor > ; -- apenas se diferente do valor default
-- a passagem para outro estado pode não depender de nenhuma "entrada"
nx_state <= D;
WHEN ...
 
 
END CASE;
END PROCESS;
------Seção de Saída (opcional):-------
-- Essa seção visa garantir que a saida new_output esteja sincronizada com o clk. 
-- Se isso não for importante, ela pode ser suprimida
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
new_output <= < valor > ;
ELSIF rising_edge(clk) THEN --or falling_edge(clk)
new_output <= output;
END IF;
END PROCESS;
END architecture;
</syntaxhighlight>
;Dica: Se ao discrever uma FSM, faltar algum estado, o Quartus dará erro durante a compilação.  Para resolver temporariamente isso pode se usar antes de encerrar o case
<syntaxhighlight lang=vhdl>
WHEN others =>
nx_state <= <initial_state>;
</syntaxhighlight>
 
:* Usando o template acima descreva em VHDL a FSM indicada na Figura 11.1.
:* Faça a simulação da FSM com Modelsim utilizando um testbench em VHDL que faça a FSM seguir os estados
<center>
<math> RST \to A \xrightarrow{\text{x=0}}  A \xrightarrow{\text{x=1}} A \xrightarrow{\text{x=2}} B \xrightarrow{\text{x=2}} B \xrightarrow{\text{x=0}} C \xrightarrow{\text{x=0}} C \xrightarrow{\text{x=2}} C \xrightarrow{\text{x=1}} A \xrightarrow{\text{x=2}} B \xrightarrow{\text{x=1}} A </math>
</center>
:: Ver pag. 277 a 280 de <ref name="PEDRONI2010b"/>
:: Note que o uso da atribuição manual do '''enum_encoding''' pode faz com que o compilador do Quartus não  reconheça a FSM, mas use logica regular para representar o sistema.
;Encontro 27  (12 jun.)
* AE16 - Controlador de Semáforo de duas vias - trabalho remoto na nuvem
;Encontro 28  (17 jun.)
* AE16 - Controlador de Semáforo de duas vias
:*Use o template da FSM para modelar o controlador semafórico da figurar a seguir.
 
{{fig|4.2|FSM - Controlador semafórico para duas vias  (diagrama de estados)|FSM_Sema2Vias.png|800 px| }}
 
;Encontro 29 (24 jun.)
* Diagrama de blocos de uma FSM completa. Diferença entre saída Moore e saída Mealy.
:No diagrama abaixo, uma FSM (''Finite State Machine'') é modelada através dos seus componentes básicos:
:* '''Entradas''' -  são os sinais que fazem a FSM  evoluir para os próximos estados.
:* '''Clock''': o clock (relógio) é o sinal que sincroniza as transições entre os estados.  A mudança sempre ocorre na transição (borda) desse sinal.
:* '''Lógica do Próximo Estado''': é um circuito combinacional que Determina o próximo estado com base no estado atual e nas entradas.
:* '''Registrador de Estado''': Armazena o estado atual
:* '''Lógica de Saída Moore''': Gera a saída apenas com base no estado atual.
:* '''Lógica de Saída Mealy''': Gera a saída com base no estado atual e na entrada.
{{fig|4.3|Diagrama de blocos de um FSM|BlockDiagramFSM.png|1000 px|}}
 
* Modelagem de FSM com Diagrama de Estados e ASM (''Algorithmic State Machine'').
{{fig|4.4|Blocos de um diagrama ASM |ASM_Block.png|600 px|Figure 10.4 de <ref name="CHU2006" />}}
 
*Exemplo da modelagem de um controlador de memória com modo de leitura '''BURST'''.
{{fig|4.5|Diagrama de estados de um controlador de memória|Mem_ctrl_SD.png|400 px|Figure 10.3 de <ref name="CHU2006"/>}}
 
{{fig|4.6|ASM de um controlador de memória|Mem_ctrl_ASM.png|400 px|Figure 10.9 <ref name="CHU2006"/>}}
* A partir da descrição da FSM em diagrama de estados ou na forma ASM, é possível implementar essa FSM em VHDL.  No código a seguir, é feita a descrição da FSM usando um código em dois segmentos, no qual o primeiro PROCESS realiza a atualização do Registrador de Estado, e o segundo PROCESS realiza a Lógica do Próximo Estado, Lógicas de Saída Moore e a Lógica de Saída Mealy.
 
<syntaxhighlight lang=vhdl>
library ieee;
use ieee.std_logic_1164.all;
entity mem_ctrl is
port (
clk            : in std_logic;
reset          : in std_logic;
mem, rw, burst : in std_logic;
oe, we, we_me  : out std_logic
);
end entity;
architecture two_seg_arch2 of mem_ctrl is
type mc_state_type is
(idle, read1, read2, read3, read4, write1);
signal state_reg, state_next : mc_state_type;
begin
process (clk, reset)
begin
if (reset = '1') then
state_reg <= idle;
elsif rising_edge(clk) then
state_reg <= state_next;
end if;
end process;
process (state_reg, mem, rw, burst)
begin
oe    <= '0';
we    <= '0';
we_me <= '0';
case state_reg is
when idle =>
if mem = '1' then
if rw = '1' then
state_next <= read1;
else
we_me      <= '1';
state_next <= write1;
end if;
else
state_next <= idle;
end if;
when write1 =>
we        <= '1';
state_next <= idle;
when read1 =>
oe <= '1';
if (burst = '1') then
state_next <= read2;
else
state_next <= idle;
end if;
when read2 =>
oe        <= '1';
state_next <= read3;
when read3 =>
oe        <= '1';
state_next <= read4;
when read4 =>
oe        <= '1';
state_next <= idle;
end case;
end process;
end architecture;
</syntaxhighlight>
Fonte: adaptado <ref name="CHU2006"/>.
 
{{fig|4.7|RTL do controlador de memória|Mem_ctrl_RTL.png|600 px| Quartus Light}}
 
{{fig|4.8|FSM do controlador de memória|Mem_ctrl_FSM.png|1000 px| Quartus Light}}
 
 
* Simulação do controlador de memória.
Na figura abaixo a FSM modelada tem duas saídas Moore ("oe" e "we"), e uma saída Mealy ("we_me").  Note que as saídas do tipo Moore sempre tem a duração de um período de clock, e elas não dependem diretamente de nenhuma entrada, mas são consequência do estado em que se encontra a FSM. No caso da saída Mealy, as entradas  afeta diretamente a saída, conforme se pode ver os gliches da entrada "mem" são transmitidas para a saída "we_me".
 
{{fig|4.9|Simulação do controlador de memoria - diferença entre a saída Moore e saída Mealy|FSM_Moore_Mealy_SIM.png|1000 px|}}
 
{{fig|4.10|Simulação de escritas, leituras simples e leitura em burst no controlador de memoria |FSM_Mem_SIM.png|1000 px|}}
 
;Encontro 30 (26 jun.)
*Circuito detector de borda
{{fig|4.11|Diagram de estados do detector de borda - implementação com saídas Moore|SD_edge_detector_moore.png|200 px| Fonte: <ref name="CHU2006"/>}}
 
<syntaxhighlight lang=vhdl>
library ieee;
use ieee.std_logic_1164.all;
entity edge_detector1 is
  port(
      clk, reset: in std_logic;
      strobe: in std_logic;
      p1: out std_logic
  );
end edge_detector1;
 
architecture moore_arch of edge_detector1 is
  type state_type is (zero, up, one);
  signal state_reg, state_next: state_type;
begin
  -- state register
  process(clk,reset)
  begin
      if (reset='1') then
        state_reg <= zero;
      elsif (clk'event and clk='1') then
        state_reg <= state_next;
      end if;
  end process;
  -- next-state logic
  process(state_reg,strobe)
  begin
      case state_reg is
        when zero=>
            if strobe= '1' then
              state_next <= up;
            else
              state_next <= zero;
            end if;
        when up=>
            if strobe= '1' then
              state_next <= one;
            else
              state_next <= zero;
            end if;
        when one =>
            if strobe= '1' then
              state_next <= one;
            else
              state_next <= zero;
            end if;
      end case;
  end process;
  -- Moore output logic
  p1 <= '1' when state_reg=up else
        '0';
end moore_arch;
</syntaxhighlight>
Fonte: <ref name="CHU2006"/>.
{{fig|4.12|Simulação do detector de borda - implementação com saídas Moore|FSM_edge_detector_moore.png|1000 px|}}
 
Ao simular o detector de borda, percebe-se que o primeiro pulso (entre 140 e 180 ps) não foi detectado, pois não durou tempo suficiente para ter o estado atualizado no próximo clock. Isso ocorre pois na saída tipo Moore, as mudanças das saídas só acontecem sincronizadas com o clock.  Note ainda que os pulsos em p1 tem a duração exata de um período de clock.
 
{{fig|4.13|Diagram de estados do detector de borda - implementação com saídas Mealy|SD_edge_detector_mealy.png|200 px| Fonte: <ref name="CHU2006"/>}}
 
<syntaxhighlight lang=vhdl>
library ieee;
use ieee.std_logic_1164.all;
entity edge_detector2 is
  port(
      clk, reset: in std_logic;
      strobe: in std_logic;
      p2: out std_logic
  );
end edge_detector2;
 
architecture mealy_arch of edge_detector2 is
  type state_type is (zero, one);
  signal state_reg, state_next: state_type;
begin
  -- state register
  process(clk,reset)
  begin
      if (reset='1') then
        state_reg <= zero;
      elsif (clk'event and clk='1') then
        state_reg <= state_next;
      end if;
  end process;
  -- next-state logic
  process(state_reg,strobe)
  begin
      case state_reg is
        when zero=>
            if strobe= '1' then
              state_next <= one;
            else
              state_next <= zero;
            end if;
        when one =>
            if strobe= '1' then
              state_next <= one;
            else
              state_next <= zero;
            end if;
      end case;
  end process;
  -- Mealy output logic
  p2 <= '1' when (state_reg=zero) and (strobe='1') else
        '0';
end mealy_arch;
</syntaxhighlight>
Fonte: <ref name="CHU2006"/>.
{{fig|4.14|Simulação do detector de borda - implementação com saídas Mealy |FSM_edge_detector_mealy.png|1000 px|}}
 
Ao simular o detector de borda, percebe-se que o primeiro pulso (entre 140 e 180 ps) agora foi detectado. Isso ocorre pois na saída tipo Mealy, as mudanças das saídas dependem do estado atual e da entrada, e por isso não são sincronizadas com o clock.  Note que agora os pulsos em p1 tem duração variável, e menor que um período de clock.
 
 
;DESAFIO1:
*Descreva o diagrama de estados abaixo em VHDL, e simule o detector de borda. Note que agora os pulsos em p1 tem duração variável, mas todos terão duração um pouco maior que um período de clock.
 
;DESAFIO2:
*Descreva os 3 diagramas de estado dos detectores de borda usando ASM.
 
 
{{fig|4.15|Diagram de estados do detector de borda - implementação com saídas Mealy melhorado|SD_edge_detector_mealy2.png|200 px| Fonte: <ref name="CHU2006"/>}}
-->
<!--
;Encontro reserva
:* Máquina de vendas
::*Use o template da FSM para modelar o sistema mostrado na figurar a seguir.
 
{{fig|7.2|FSM - Máquina de vendas (diagrama de estados)|FSM_MVD.png|800 px|Adaptado da Figura 11.3 de <ref name="PEDRONI2010b"/> }}
 
{{fig|7.3|FSM - Máquina de vendas (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 vendas (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].
 
;DESAFIO:
*Implementar um controlador para máquina de Lavar Roupas baseado na FSM abaixo.
 
{{fig|7.4|FSM da Máquina de Lavar Roupas |FSM_LavaRoupas.png|1200 px|}}
 
;PARA A PRÓXIMA AULA:
* Implementação em VHDL da FSM de máquina de Lavar Roupas
* Simulação em ModelSim da FSM de máquina de Lavar Roupas
-->
{{collapse bottom}}
 
===Unidade 5 - Metodologia RT (Register Transfer)===
* 7 ENCONTROS
{{collapse top | expand=true | Unidade 5 - Metodologia RT (Register Transfer)}}
<!--
A fonte principal dessa unidade é o capítulo 11 e 12 do livro "RTL Hardware Design Using VHDL: Coding for Efficiency, Portability, and Scalability, P. P. Chu." <ref name="CHU2006"/>  É recomendado que os alunos leiam estes capítulos e usem como fonte de consulta.
;Encontro 31 (1 jul.)
:* Um algoritmo é uma sequência detalhada de ações ou passos para realizar uma tarefa ou resolver um problema. Como a semântica das linguagens de programação tradicionais também se baseia na execução sequencial, um algoritmo pode ser facilmente convertido em um programa utilizando as construções dessas linguagens. O programa, então, é compilado em instruções de máquina e executado em um computador de uso geral.
*Exemplo de '''algoritmo que soma de 4 números''' e divide o resultado por 8.
<pre>
# entrada a(0), a(1), a(2) e a(3)
# saída out_q
size = 4
sum = 0;
for i in (0 to size - 1) do {
    sum = sum + a(i);
}
q = sum / 8;
r = sum rem 8;
if (r > 3) {
    q = q + 1;
}
out_q = q;
</pre>
O algoritmo primeiro soma os elementos individuais e armazena o resultado em uma variável chamada sum. Em seguida, usa as operações de divisão (/) e de resto (rem) para encontrar o quociente e o resto. Se o resto for maior que 3, adiciona-se 1 extra ao quociente para realizar o arredondamento.
 
*Uma variável em um algoritmo ou pseudocódigo pode ser interpretada como uma "localização de memória com um endereço simbólico" (ou seja, o nome da variável). Ela é usada para armazenar um resultado intermediário de um cálculo. Por exemplo, na segunda instrução, o valor 0 é armazenado na localização de memória com o endereço simbólico sum. Dentro do laço for, o valor a(i) é somado ao conteúdo atual de sum, e o resultado da soma é armazenado de volta na mesma localização. Na quarta instrução, o conteúdo de sum é dividido por 8 e o resultado é armazenado em uma localização de memória com um endereço simbólico. 
 
*A execução de um algoritmo é realizada de forma sequencial, e a ordem dos passos é importante. Por exemplo, a soma dos elementos precisa ser feita antes que a operação de divisão possa ser executada. Note que a ordem de execução pode depender de certas condições, como nos comandos for e if.
 
*O algoritmo poderia ser descrito na forma estrutural baseada em fluxo de dados usando VHDL desenrolando o laço do algoritmo e converter as variáveis em sinais de conexão internos. Suponha que sum seja um sinal de 8 bits. Além disso a divisão por 8 pode ser implementado através de uma rotação a direita de 3 posições, sendo o resto os bits que foram rotacionados (2 downto 0).
<pre>
sum(0) <= a(0);
sum(1) <= sum(0) + a(1);
sum(2) <= sum(1) + a(2);
sum(3) <= sum(2) + a(3);
q <= "000" & sum(3)(7 downto 3);
r <= "00000" & sum(3)(2 downto 0);
out_q <= q + 1 when (r > 3) else q;
</pre>
* A implementação estrutural baseada em fluxo de dados não é geral e só pode ser aplicada a algoritmos simples e triviais.
* As duas variações a seguir do algoritmo anterior ilustram a limitação dessa abordagem.
:* Em primeiro, vamos considerar um vetor com 10 elementos. No pseudocódigo, isso pode ser feito substituindo o número 4 por 10 na primeira instrução. Isso aumenta o número de iterações do laço. Podemos desenrolar o laço (loop unrolling) e derivar a implementação estrutural baseada em fluxo de dados, o que exigiria nove somadores. Se o número de elementos do vetor continuar a crescer, o '''número de somadores aumentará''' proporcionalmente. Claramente, essa abordagem exige recursos de hardware excessivos e não é prática para um vetor maior.
:*Em segundo lugar, vamos supor que o '''tamanho do vetor não seja fixo''', mas seja '''especificado por uma entrada adicional, n'''. Para realizar isso no algoritmo, basta substituir o valor fixo na primeira instrução por n, ou seja, fazer size = n. Isso será muito difícil de implementar com uma abordagem estrutural baseada em fluxo de dados. Como o hardware não pode se expandir ou encolher dinamicamente, seria necessário construir um circuito capaz de calcular os resultados para todos os possíveis valores de n e, em seguida, usar um multiplexador para direcionar o valor desejado para a saída.
 
*A '''metodologia de transferência entre registradores''' ('''metodologia RT''') é voltada para possibilitar realizar algoritmos em hardware.
As características principais dessa metodologia RT são:
:* Usar '''registradores''' para armazenar os dados intermediários e imitar as variáveis utilizadas em um algoritmo;
:* Usar um '''caminho de dados''' (datapath) personalizado para realizar todas as operações necessárias com os registradores;
:* Usar um '''caminho de controle''' (control path) personalizado para especificar a ordem das operações nos registradores.
 
*Quando um algoritmo é implementado usando a metodologia RT, a manipulação e o roteamento dos dados são realizados por hardware dedicado. O circuito de manipulação de dados, a rede de roteamento e os registradores, juntos, são conhecidos como o '''caminho de dados''' ('''data path''').
 
*Como um algoritmo é descrito como uma '''sequência de ações''', precisamos de um circuito que controle quando e quais operações de transferência entre registradores devem ocorrer. Esse circuito é conhecido como '''caminho de controle''' ('''control path''').
 
*Um '''caminho de controle''' pode ser '''implementado por uma máquina de estados finitos (FSM)''', que pode usar estados para impor a ordem dos passos desejados e caixas de decisão para imitar os desvios (branches) e iterações (laços) de um algoritmo.
 
* Podemos usar uma máquina de estados finita estendida (FSM estendida) para descrever a operação geral do sistema. Ela é conhecida como '''FSM com caminho de dados''' ('''FSMD''').
* A principal diferença entre uma variável em um algoritmo e um registrador em um sistema com clock é que neste último as operações são feitas implicitamene como operações de transferência de registros (Operação básica de RT). Sua forma básica é:
rdest ← f(rsrc1, rsrc2, ...);
* A interpretação dessa operação é:
:* Na borda de subida do clock, as saídas dos registradores '''rsrc1, rsrc2''', etc., ficam disponíveis;
:* Essas saídas são enviadas para um circuito combinacional que executa a função '''f( )''' (por exemplo: soma, multiplicação, deslocamento, etc.);
:* Na próxima borda de subida do clock, o resultado da operação é armazenado no registrador de destino '''rdest'''.
 
*Ver slides do  [https://drive.google.com/file/d/1-w9S39oHsx70K4Gom3i-y1WfQPyvv10d/view?usp=drive_link capítulo 11] (slide 1 a 30).
 
*Visão geral do FSMD
{{fig|5.1|Diagrama de blocos básico de uma FSMD |FSMD_block_diagram.png|500 px|  <ref name="CHU2006"/>}}
 
;Encontro 32 e 33 (3 e 8 jul.) - Multiplicador por adição repetitivas.
''Nota: Este exemplo é apresentado no livro  <ref name="CHU2006"/> na seção 11.3''
 
Considere um multiplicador como os dois operandos da multiplicação sendo '''a_in''' e '''b_in''', e a saída '''r_out''' onde todos os três sinais são do tipo UNSIGNED. Um algoritmo sequencial simples consiste em somar '''a_in''' repetidamente por'''b_in''' vezes. Por exemplo, 7×5 pode ser calculado como 7 + 7 + 7 + 7 + 7. Embora esse método não seja eficiente, ele é simples, e permite apreender a elaboração do diagrama ASMD e do hardware.
;Pseudocódigo do algoritmo:
Esse algoritmo pode ser representado pelo pseudocódigo:
<pre>
if (a_in = 0 or b_in = 0) then
    r_out = 0
else
    a = a_in
    n = b_in
    r = 0
    while (n ≠ 0)
        r = r + a
        n = n - 1
    r_out = r
</pre>
Como o diagrama ASMD não possui uma construção de laço (loop), mas usa uma caixa de decisão com uma condição booleana para escolher um entre dois caminhos de saída possíveis. Portanto é semelhante a uma combinação de '''if''' com instrução '''goto'''. O pseudocódigo revisado fica assim:
<pre>
    if (a_in = 0 or b_in = 0) then
        r_out = 0
    else
        a = a_in
        n = b_in
        r = 0
op:    r = r + a
        n = n - 1
        if (n = 0) then
            goto stop
        else
            goto op
stop:  r_out = r
</pre>
 
;ASMD do algoritmo:
Observe na ASMD abaixo que os sinais '''start''' (início) e '''ready''' (pronto) foram adicionados para permitir a operação sequencial do sistema. Imaginando o multiplicador sequencial como parte de um sistema principal, quando ele deseja executar uma operação de multiplicação, primeiro verifica o sinal '''ready'''. Se estiver alto, coloca os dois operandos nas entradas de dados '''a_in''' e '''b_in''' e ativa o sinal '''start'''. Ao detectar o sinal start, o multiplicador sequencial captura os operandos e inicia o processamento. Após a conclusão do cálculo, o sinal ready é ativado para informar ao sistema principal que o resultado está disponível em '''r_out'''.
 
O diagrama ASMD, mostrado na figura abaixo, segue de forma fiel o pseudoalgoritmo. Ele utiliza os registradores de dados '''n''', '''a''' e '''r''' para representar as três variáveis do algoritmo, emprega caixas de decisão para implementar as estruturas condicionais (if) e utiliza operações de transferência entre registradores (operações RT) para executar as instruções sequenciais.
 
{{fig|5.2|Diagrama ASMD do algoritmo multiplicador L11.1 |ASMD_mult_sum.png|400 px|  <ref name="CHU2006"/>}}
 
;FSMD do algoritmo:
 
;Construção do CONTROL PATH:
 
A construção do '''caminho de controle''' (CONTROL PATH) (1 - next state logic), (2 - state reg) e (3 - output logic) é a mesma utilizada com a máquina de estados (FSM). Os sinais dentro da caixa de decisão são as entradas da FSM. No diagrama ASMD, as expressões booleanas utilizam quatro sinais: '''start''' (comando externo) e '''a_is_0''' (8), '''b_is_0'''(9) e '''count_0''' (10) ('''sinais de status''' internos, provenientes do caminho de dados). Eles são ativados quando as condições correspondentes são satisfeitas. Os sinais (8) e (9) são resultado direto da comparação das entradas a_in = 0 e 'b_in = 0.  O sinal (10) por utilizar um sinal interno necessita utilizar a entrada do registrador '''n''' (n_next = 0).
 
A saída do caminho de controle inclui o sinal externo de status '''ready''' (pronto) e os '''sinais de controle''' que especificam as operações de transferência entre registradores (operações RT) no '''caminho de dados'''. Neste exemplo, foi usada a saída do registrador de estado como sinal de controle ('''idle''', '''ab0''', '''load''', '''op'''), os quais controlam a seleção nos multiplexadores usados na rede de roteamento do caminho de dados.
 
;Construção da DATA PATH:
A construção do caminho de dados pode ser derivada de forma sistemática seguindo diretrizes simples:
:1 - Liste todas as '''operações RT''' possíveis no diagrama ASMD, incluindo as operações RT padrão (default).
:2 - Agrupe as operações RT de acordo com seus registradores de destino.
:3 - Para cada grupo, derive o circuito seguindo o processo:
::(a) Construa o registrador de destino.
::(b) Construa os circuitos combinacionais envolvidos em cada operação RT.
::(c) Adicione circuitos de multiplexação e roteamento se o registrador de destino estiver associado a múltiplas operações RT.
:4 - Adicione os circuitos necessários para gerar os sinais de status.
 
No exemplo da multiplicação por adição repetitiva  as operações RT
*com o registrador r:
:r ← r (no estado idle)
:r ← 0 (nos estados load e ab0)
:r ← r + a (no estado op)
*com o registrador n:
:n ← n (no estado idle)
:n ← b-in (nos estados load e ab0)
:n ← n - 1 (no estado op)
*com o registrador a:
:a ← a (nos estados idle e op)
:a ← a-in (nos estados load e ab0)
 
{{fig|5.3|FSMD do algoritmo multiplicador L11.1 |FSMD_mult_sum.png|600 px|  <ref name="CHU2006"/>}}
 
;Melhoria da implementação do algoritmo com saída Mealy:
Observando o ASMD acima, pode-se perceber que as saídas do estado ab0 e load são as mesmas, e portanto elas poderiam ser inseridas após a decisão '''start = 1''', como saídas Mealy.  Essa modificação produz um novo ASMD para o mesmo algoritmo, que apenas tem 2 estados.
 
{{fig|5.4|Diagrama ASMD do algoritmo multiplicador L11.6 (saída Mealy) | ASMDMealy_mult_sum.png|400 px|  <ref name="CHU2006"/>}}
 
*Testar as implementações em VHDL dos  [https://drive.google.com/file/d/1f7DqWL9390nTGgXUVdd01CaSAJX-UxOC/view?usp=drive_link Listing 11.1 a L11.6] de  <ref name="CHU2006"/>.
 
;Encontro 34 (10 jul.) - Multiplicador por adição repetitivas.
*Simulação essa FSMD, verificando o funcionamento da FSM através da simulação no MODELSIM.  Teste com multiplicações por zero  (0 x 31 = 0); (31 x 0 = 0), multiplicações menores  (2 x 31 = 62); (31 x 2 = 62)  e multiplicações maiores (9 x 31 = 279) (31 x 9 = 279).
:*Anote a '''Fmax''' e meça o número de clocks ('''N_clk''') transcorrido entre duas bordas de subida do sinal '''READY'''. Dica use dois cursores para medir o tempo total , e divida pelo período do clock utilizado na simulação.
 
:* Analise se ocorre alguma melhorias em termos de tempo de processamento ('''N_clk/Fmax''') e número de elementos lógicos nas versões L11.1 a L11.3, L11.5 e L11.6.  Também verifique se o resultado está correto em todas as versões.
<center>
{| class="wikitable" style="text-align:center;"
|- style="font-weight:bold;"
! style="background-color:#c0c0c0;" | Listing 11.
! colspan="2" style="background-color:#c0c0c0;" | 1
! colspan="2" style="background-color:#c0c0c0;" | 2
! colspan="2" style="background-color:#c0c0c0;" | 3
! colspan="2" style="background-color:#c0c0c0;" | 5
! colspan="2" style="background-color:#c0c0c0;" | 6
|- style="text-align:left;"
| style="text-align:center;" | Fmax
| colspan="2" |
| colspan="2" |
| colspan="2" |
| colspan="2" |
| colspan="2" |
|- style="font-weight:bold; background-color:#c0c0c0;"
| || Nclk || Top || Nclk || Top || Nclk || Top || Nclk || Top || Nclk || Top
|-
| 0x31
|
|
|
|
|
|
|
|
|
|
|-
| 31x0
|
|
|
|
|
|
|
|
|
|
|-
| 2x31
|
|
|
|
|
|
|
|
|
|
|-
| 31x2
|
|
|
|
|
|
|
|
|
|
|-
| 9x31
|
|
|
|
|
|
|
|
|
|
|-
| 31x9
|
|
|
|
|
|
|
|
|
|
|}
</center>
 
;Encontro 35 a 37 (15 a 22 jul.) - Revisão de projeto hierárquico.
* Implementar um controlador de semáforo construído com os seguintes componentes:  1 divisor de clock ('''div_clk'''), 1 temporizador de segundos com contagem crescente em BCD ('''timer_bcd'''), 2 conversores de BCD para SSD ('''bcd2ssd'''), uma FSM para semáforo de 2 vias ('''FSM_2vias''').
* Os componentes devem ser declarados como STUB, isto é a '''archicteture''' deve estar vazia.  Isso facilita o entendimento do projeto hierárquico sem a ocorrência de erros internos nos componentes.
* O desenvolvimento dos componentes pode ser postergado para uma segunda etapa do projeto.
* Ao final da atividade os alunos devem enviar a [https://moodle.ifsc.edu.br/mod/assign/view.php?id=296897 AE17 - Controlador de Semáforo de duas vias (simulação de entrega)]
{{fig|5.30|Diagrama de RTL do top level  |RTL_TL.png|800 px| Igor & Ygor 2025}}
 
-->
<!--
;Encontro 35 (18 fev.)
*Implementação de um multiplicador por deslocamento de bits e somas sequenciais
*Implemente em VHDL o [https://drive.google.com/file/d/1f7DqWL9390nTGgXUVdd01CaSAJX-UxOC/view?usp=drive_link Listing 11.7  de  <ref name="CHU2006"/>]
{{fig|4.14|Diagrama ASMD do algoritmo multiplicador  L11.7 e 11.8 |ASMD_mult_shift_sum.png|300 px|  <ref name="CHU2006"/>}}
*Análise de tempo e desempenho do FSMD
 
*Implementação de um multiplicador por somas sucessivas em dataflow (a + a + a + ...)
*Implementação de um multiplicador pelo bloco multiplicador  (a x b)
 
;Encontro 36 a 39 (20, 22, 25, 27 fev.)
*Realização da [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE4_-_Compara%C3%A7%C3%A3o_de_Hardware_projetado_por_FSMD_e_Dataflow AE4 - Comparação de Hardware projetado por FSMD e Dataflow]
 
;Encontro 40 (6 mar.)
*Atividade de recuperação para alunos com conceito inferior a 6. 
*Os demais alunos foram dispensados
 
<!--
;Encontro 36 (20 ago.)
*Circuito gerador de pulso (Implementação em lógica regular, em FSM, em FSMD)
{{fig|4.14|Diagrama ASMD do algoritmo do gerador de pulso|ASMD_pulse_generator.png|600 px|  <ref name="CHU2006"/>}}
*Circuito para cálculo do máximo divisor comum (gcd)
{{fig|4.15|Diagrama ASMD do algoritmo do GCD|ASMD_gcd.png|600 px|  <ref name="CHU2006"/>}}
 
;Encontro 37 (23 ago.)
*Avaliação A2
Implemente o algoritmo original de Euclides usando a metodologia RT. 
 
Ver descrição em [https://seriouscomputerist.atariverse.com/media/pdf/book/Art%20of%20Computer%20Programming%20-%20Volume%202%20(Seminumerical%20Algorithms).pdf] .
- GCD é descrito em 4.5.2. The Greatest Common Divisor), pag 346 do PDF
- Algorithm E (Original Euclidean algorithm). pag 349 do PDF.
 
- Apresente um relatório com a simulação mostrando como obteve o número de clocks necessários para realizar o cálculo, que inclua uma tabela comparando os algoritmos. 
- Obtenha os dados de numero de elementos lógicos, Tempo de cálculo, e compare com os dois algoritmos do gcd slow e fast.
 
Enviar nesta tarefa os arquivos
Q1.QAR, Q1-RTL.PNG, Q1-TM.PNG, Q1-SIM.PNG e o relatório
 
Os arquivos tb_XXX.do e wave.do devem ser enviados dentro do QAR
 
Pontuação
*7 pontos - pelo relatório e projeto com os  resultados dos algoritmos gcd slow e fast.
*3 pontos - pelo relatório e projeto com os  resultados do "Original Euclidean algorithm" em dataflow ou RT metodology
-->
{{collapse bottom}}
 
==Avaliações==
Durante o semestre serão realizadas 2 avaliações e várias atividades feitas extra classe.
 
;Data das avaliações:
*A1 : Avaliação A1 (peso 35) XX/2025
*A2 : Avaliação A2 (peso 45) XX/2025
*AEs : Média ponderada das AEs  (peso 20)
*R1 : Recuperação de A1 : XX/2025
*R2 : Recuperação de A2 : XX/2025
*[[Folha de consulta de VHDL]]
 
<!--
== Atividade relâmpago (AR) ==
As atividades relâmpago devem ser entregues no Moodle da disciplina. A não entrega dessas atividades não gera nenhum desconto, apenas geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN.
<!--
===AR1 - Conhecendo os dispositivos lógicos programáveis===
;Atividade:
Para esse desafio, no PASSO 3 da AE1, selecione o dispositivo EP4CE6E22C7 da família Cyclone IV E.
 
Utilizando o circuito que realiza o cálculo da distância de Hamming entre dois sinais, procure melhorar o processo de compilação de modo que consiga reduzir ao máximo o tempo de propagação entre entrada e saída.
 
*Insira restrições de atraso máximo para o compilador utilizando o Synopsys Design Constraints File
*Modifique a técnica utilizada pelo Quartus na otimização em em Optimization Technique por default está selecionado [x] Balanced (Normal flow) .
:*selecione uma das opções de [x] Performance para "procurar" reduzir o tempo de propagação e/ou aumentar a frequência máxima do sistema.
:*selecione uma das opções de [x] Power para "procurar" reduzir a potência utilizados no sistema.
:*selecione [x] Area para "procurar" reduzir o número de elementos lógicos utilizados no sistema.
*Altere a semente iniciaal em Fitter Initial Placement Seed.
 
;Entregas:
*Envie o QAR com o projeto compilado e configurado com menor tempo de propagação entre entrada e saída que você conseguiu.
*Envie a captura da imagem mostrando o relatório com este tempo.
*Envie no texto online os seguintes dados:
:1) Optimization Technique usada
:2) Fitter Initial Placement Seed usada
:3) Paramentros usados no  Synopsys Design Constraints File
:4) O caminho crítico (aquele que tem o maior tempo de propagação) e o tempo obtido.
 
;Bonificação na A1:
*0,5 - para o(a) estudante que obtiver o menor tempo de propagação para o caminho crítico
*0,3 - para o(a) estudante que obtiver o segundo menor tempo de propagação para o caminho crítico
*0,2 - para o(a) estudante que obtiver o terceiro menor tempo de propagação para o caminho crítico
 
===AR2 - Desafio: contador bidirecional===
; Atividade:
Implementar um contador bidirecional entre MIN e MAX. Uma entrada DIR indica a direção da contagem. Considere DIR = 0 (para contagem crescente) e DIR = 1 (para contagem decrescente). Avaliar a frequencia máxima (Fmax) em que o circuito funcionará utilizando o '''dispositivo EP4CE10F17A7'''.
*Versão 1: Com underflow no valor mínimo (MIN) e overflow no máximo (MAX).
*Versão 2: Com parada no valor mínimo (MIN), se decrescente e também no máximo (MAX) se crescente.
 
;Entregas:
* Para realizar a simulação e análise de tempo use MIN = 2 e MAX = 13.
* Envie o QAR com o projeto compilado e configurado com o '''maior valor de Fmax''' que você conseguiu.
* Envie a captura da imagem mostrando o relatório com essa frequência.
* Envie a tela da simulação que mostra que o contador funciona (faça contar de 0 até MAX, e também decrementar até o MIN)
* Envie no texto online os seguintes dados:
:1) Qual versão foi implentada (v1 ou v2)
:2) O maior valor de Fmax obtido
 
;Bonificação na A1:
*1,0 - para  o(a) primeiro estudante que enviar o contador funcionando (versão 1 ou 2)
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 1)
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 2)
 
;Dicas:
* [[Restringir a frequencia máxima de clock no Quartus II]]
* [[Como obter o Fmax do projeto no Quartus]]
 
===AR3 - Desafio: contador bcd===
; Atividade:
Implementar um contador BCD de 00 a 99, com parada em qualquer valor MAX_DU. Se os parâmetros dos contador D = 5 e U = 9, isso implica em contar de 00 até 59 e ficar parado neste valor. A atingir o valor final MAX_DU, uma saída adicional OPA deve ser ativada. Avaliar a frequencia máxima (Fmax) em que o circuito funcionará utilizando o '''dispositivo EP4CE10F17A7'''.
 
*Versão 1: O contador '''crescente''' deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com parada em MAX_DU.
*Versão 2: O contador '''crescente''' deve fazer a contagem em binário, e incrementar 6 nos bits da unidade sempre que passar de 9(1001) para 10 (1010), com parada em MAX_DU.
*Versão 3: O contador '''decrescente''' deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com início em MAX_DU e parada em 00.
 
;Entregas:
* Na simulação e na análise considere a contagem de 00 a 23, definindo os parâmetros D = 2 e U = 3.
* Envie o QAR com o projeto compilado e configurado com o '''maior valor de Fmax''' que você conseguiu.
* Envie a captura da imagem mostrando o relatório com essa frequência.
* Envie a tela da simulação que mostra que o contador funciona fazendo ele contar de 0 até 23 (ou 23 até 0), deixe o período a mais no final para mostrar que o contador parou.
* Envie no texto online os seguintes dados:
:1) Qual versão foi implentada (v1, v2 ou v3).
:2) O maior valor de Fmax obtido.
:3) Qual o número de elementos lógicos utilizados no projeto.
 
;Bonificação na A1:
*1,0 - para  o(a) primeiro estudante que enviar o contador funcionando (versão 1, 2 ou 3)
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 1)
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 2)
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 3)
-->
 
== Atividade extra-classe (AE) ==
A média ponderada das atividades extra-classe será considerada no cálculo do conceito final da UC.  A entrega das mesmas será feita pelo Moodle, e cada dia de atraso irá descontar 0,2 na nota da atividade.  Muitas dessas atividades também geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN.  Para os BÔNUS só serão considerados projetos entregues no prazo.
<!--
===AE1 -  Conhecendo os dispositivos lógicos programáveis===
{{collapse top | expand=true| bg=lightyellow | AE1 -  Conhecendo os dispositivos lógicos programáveis}}
;Objetivos:
*Conhecer o Quartus Prime e as características dos dispositivos lógicos programáveis
*Analisar os tempos de propagação em um circuito combinacional
*Alterar configurações do compilador
*Fazer a simulação funcional e temporal de um circuito combinacional.
 
;Atividades:
*'''PASSO 1:''' Realize a atividade descrita em [[Conhecendo os dispositivos lógicos programáveis - QUARTUS PRIME]]
:*Ao escolher a família de FPGAS, escolha inicialmente um dispositivo da família '''Max II'''. Anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo.
:*Capture as telas solicitadas e depois utilize-as no relatório da atividade.
:*Anote o tempo utilizado para cada uma das etapas do processo de compilação.
:*Anote o número de '''elementos lógicos configuráveis''' utilizados e o número de pinos utilizados, bem com o percentual em relação ao número total do dispositivo.
:*Anote algum erro ('''Error''') ou alertas ('''Warnings''') que o Quartus II indicar no painel de mensagens '''[Messages]'''
:*Ao final salve o projeto em um arquivo QAR (sugestão PJ1.QAR)
 
*'''PASSO 2''': Repita a atividade descrita em [[Conhecendo os dispositivos lógicos programáveis - QUARTUS PRIME]], trocando a família e dispositivo a ser usado na implementação.  Escolha nesta vez um dispositivos da família '''Cyclone IV E''', '''Cyclone V''', '''Cyclone 10'''  ou  '''Arria 10'''. Anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo.
:*Observe as mudanças que ocorrem tanto no tipo de elemento lógico configurável, no Chip Planner, no Pin Planner, e no circuito dos pinos de I/O.  Note que estes FPGAs também apresenta novos componentes, tais como: Memória, Multiplicadores, DSP, PLL, DLL, etc. Verifique se consegue encontra-los no leiaute mostrado no Chip Planner,  e documente aqueles que encontrar.
:*Compare os resultados obtidos nos procedimentos do PASSO 1 e PASSO 2.
 
*'''PASSO 3''': Realize o procedimento descrito em [[Medição de tempos de propagação em circuitos combinacionais - Quartus Prime]], com o circuito  '''hamming_distance'''.
:*Ao escolher a família de FPGAS, escolha um dispositivo FPGA da família '''Cyclone IV E'''. Anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo.
:*Capture as telas mostradas no roteiro e depois utilize-as no relatório da atividade.
:*Anote o máximo tempo de propagação entre entrada e saída.
:*Anote o número de elementos lógicos utilizados e o número de pinos utilizados, bem com o percentual em relação ao número total do dispositivo.
:*Experimente modificar as configurações do compilador, conforme mostrado em '''Configurando o compilador'''.  Se desejar mude a semente inicial trocando o valor de '''[Seed: 1]'''
:*Experimente inserir diferentes restrições de atraso máximo para o compilador, e analise o resultado obtido.
:*Anote algum erro ('''Error''') ou alertas ('''Warnings''') que o Quartus II indicar no painel de mensagens '''[Messages]'''
:*Ao final salve o projeto em um arquivo QAR (sugestão PJ2.QAR)
 
*'''PASSO 4''': Realize a simulação funcional do circuito  '''hamming_distance'''
:*Capture as telas que mostram o circuito funcionando e depois utilize-as no relatório da atividade.
 
;Entregas:
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar cada um dos projetos.
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa.  O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão.  A descrição dos procedimentos feita na página wiki não precisa incluída no relatório.
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida.
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
{{collapse bottom}}
 
===AE2 - Contador BCD 000 a 999===
{{collapse top | expand=true| bg=lightyellow | AE2 - Contador BCD 000 a 999}}
;Objetivos:
*Construir um contador BCD de 000 a 999, utilizando um código de dois segmentos.
:*o primeiro segmento contém apenas a parte sequencial
:*o segundo segmento contém a parte combinatorial '''Next State Logic''' e lógica de saída
*Analisar o desempenho de um circuito pelo Fmax.
 
;Passo 1 - Projeto um contador BCD:
*Projete um contador BCD que conte, Unidades, Dezenas, Centenas.
<syntaxhighlight lang=vhdl>
entity contador_bcd is
    Port ( clock    : in  std_logic;
          reset    : std_logic;
          enable  : std_logic;
          centena  : out std_logic_vector(3 downto 0);
          dezena  : out std_logic_vector(3 downto 0);
          unidade  : out std_logic_vector(3 downto 0)
    );
end entity;
</syntaxhighlight>
*Capture o diagrama RTL do contador.
 
;Passo 2 - Realize a simulação funcional do circuito do contador BCD:
*Faça a simulação do contador realizando a contagem de 0 a 999 e novamente até 999.  Verifique se o contador retorna a zero após o overflow em 999.
*Utilize como clock um sinal de 1 sec, e escolhe como escala de tempo o sec (segundo) no Wave do Modelsim.
*Capture detalhes da simulação que mostram as contagem das Unidades, Dezenas, Centenas e também o Overflow.  Use tantas capturas quantos achar necessário.
 
;Passo 3 - Otimização de área e desempenho em Fmax
*Use a família de FPGAS '''Cyclone IV E''', o dispositivo EP4CE6E22A7. Anote a tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo.
* Utilize o procedimento descrito em [[Como obter o Fmax do projeto no Quartus]].
* Anote a Fmax do projeto (do modelo Slow 1200mV 125ºC), número de elementos lógicos utilizados e o número de pinos utilizados.
* Utilize o procedimento indicado em [[Restringir a frequencia máxima de clock no Quartus]], modificando a frequencia do clock de modo a forçar o compilador a obter melhores resultados.
* Anote a Fmax do projeto, número de elementos lógicos utilizados e o número de pinos utilizados.
* Experimente modificar as configurações do compilador, conforme mostrado em '''Configurando o compilador'''.  Se desejar mude a semente inicial trocando o valor de '''[Seed: 1]'''
* Anote a Fmax do projeto, número de elementos lógicos utilizados e o número de pinos utilizados, e eventuais elementos DSPs utilizados.
* Apresente os resultados obtidos em uma tabela única.
 
;Entregas:
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar o projeto.
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa.  O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão.  A descrição dos procedimentos feita na página wiki não precisa incluída no relatório.
#O relatório deve indicar os ajustes que foram feitos para obter a maior Fmax e o menor número de elementos lógicos.
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida.
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
 
;Bônus:
*1 ponto na Avaliação A1 para o(a) estudante que apresentar o projeto que funcione com a maior Fmax.
*0,5 ponto na Avaliação A1 para o(a) estudante que apresentar o projeto com o menor número de elementos lógicos.
*0,5 ponto na Avaliação A1 para o(a) estudante que apresentar o projeto que funcione com o segundo maior Fmax.
*0,3 ponto na Avaliação A1 para o(a) estudante que apresentar o projeto com o segundo menor número de elementos lógicos.
:*Em caso de empate, o critério de desempate é a data de entrega
:*Cada estudante pode receber no máximo 1 ponto na Avaliação A1 através da AE2.
 
{{collapse bottom}}
 
===AE3 - Contador BCD genérico ===
{{collapse top | expand=true| bg=lightyellow | AE3 - Contador BCD genérico}}
;Objetivos:
*Construir um contador BCD genérico, que permita definir qualquer número de dígitos BCD, desde 1 até N, utilizando um código de dois segmentos.
:*o primeiro segmento contém apenas a parte sequencial
:*o segundo segmento contém a parte combinatorial '''Next State Logic''' e lógica de saída
*Criar tipos de dados e utiliza-los como portas da entity e sinais internos.
*Utilizar estruturas de repetição de hardware.
*Gerar e utilizar sinais de Enable para ativar os diversos contadores de 0 a 9.
*Analisar o desempenho de um circuito pelo Fmax.
 
;Passo 1 - Projeto um contador BCD genérico:
*Projete um contador BCD genérico, que conte, Unidades, Dezenas, Centenas, Unidades de Milhar, Dezenas de Milhar, etc. conforme solicitado no parâmetro genérico N.
*Obtenha um contador para 3 digitos BCD, e capture o diagrama RTL do contador.
*Obtenha um contador para 6 digitos BCD, e capture o diagrama RTL do contador.
 
;Passo 2 - Realize a simulação funcional do circuito do contador BCD genérico:
*Faça a simulação do contador para N = 3 digitos BCD.  Verifique se o contador retorna a zero após o overflow em 999.
*Capture detalhes da simulação que mostram as contagem das Unidades, Dezenas, Centenas e também o Overflow.  Use tantas capturas quantos achar necessário.
 
;Passo 3 - Geração de um sinal de Enable a cada 1 ms.
* Projete um circuito que gere um sinal de enable para o contador de miléssimo de segundo. O sinal de Enable deve durar exatamente o período do clock do kit a ser utilizado.
* A geração do sinal de Enable só deve ocorrer se a entrada START estiver em 1.
*Conecte esse circuito ao contador BCD com N = 5, sendo que os 2 digitos mais significativos devem contar os segundos, e os 3 dígitos menos significativos os milessimos de segundo.
 
;Passo 4 - Implemente o contador com o divisor de clock no kit
*Utilize o kit DE2-115 na implementação do contador de 0 a 99,999 sec. Ver [[Preparando para gravar o circuito lógico no FPGA]]
*Ao escolher a família de FPGAS, escolha o dispositivo FPGA da família '''Cyclone IV E''' do kit e anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo.
* Utilize o procedimento indicado em [[Restringir a frequencia máxima de clock no Quartus]], modificando a frequencia do clock de modo a definir o clock desejado como 50MHz, pois é o clock do kit a ser utilizado
* Utilize o procedimento descrito em [[Como obter o Fmax do projeto no Quartus]]
* Anote a Fmax do projeto, número de elementos lógicos utilizados e o número de pinos utilizados.
* Verifique o funcionamento correto do contador comparando o tempo total da contagem 100 segundos com um cronometro (https://dollyclock.com/pt/stopwatch)
 
;Dicas:
*Para replicar um hardware N vezes vai precisar instruções como FOR GENERATE e FOR LOOP.
*Para gerar N saída BCD com 4 bits para cada dígito, será necessário criar um novo tipo de dado.
  type bcd_digits is array (natural range <>) of unsigned(3 downto 0);
  signal bcd  : bcd_digits(0 to N-1);
*Para que um tipo seja conhecido na declaração das portas é necessario incluir essa declação do tipo em um pacote e incluir o pacote no arquivo.
<syntaxhighlight lang=vhdl>
-- FILE : ifsc_pkg.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
package ifsc_pkg is
    type bcd_digits is array (natural range <>) of unsigned(3 downto 0);
end package;
</syntaxhighlight>
 
;Entregas:
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar o projeto.
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa.  O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão.  A descrição dos procedimentos feita na página wiki não precisa incluída no relatório.
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida.
#Grave um vídeo mostrando que o contador está funcionando de acordo com o cronometro, e disponibilize o link para o vídeo.
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
{{collapse bottom}}
 
===AE4 - Análise de contadores digitais ===
{{collapse top | expand=true| bg=lightyellow | AE4 - Análise de contadores digitais}}
;Objetivos:
*Implementar e simular diferentes tipos de contadores digitais:
:*Contador binario sequencial;
:*Contador Gray; 
:*Contador em anel;
:*Contador Johnson e
:*Contador LFSR.
*Acrescentar um sinal de '''Enable''' em cada um dos contadores fornecidos em aula.
*Todos os contadores devem ser implementados em 2 segmentos de código (parte sequencial e parte combinatória)
*Analisar a influência do tipo de contador e número de bits sobre a área usada (número de elementos lógicos) e desempenho em velocidade (Fmax).
;Divisão em equipes:
*As equipes (ou estudante individual) deverão modificar os contadores vistos em aula para que fique com a seguinte quantidade de bits:
<pre>
E1 - 5 e 15 bits
E2 - 6 e 14 bits
E3 - 7 e 13 bits
E4 - 8 e 18 bits
E5 - 7 e 10 bits
E6 - 8 e 17 bits
I1 - 9 bits
I2 - 11 bits
I3 - 12 bits
I4 - 16 bits
I5 - 13 bits
I6 - 14 bits
I7 - 18 bits
I8 - 19 bits
I9 - 17 bits
</pre>
*Nos trabalhos individuais apenas um contador de cada tipo será implementado e simulado. 
*Nos trabalhos em equipe dois contadores precisam ser implementados e simulados.
 
;Em todos os contadores:
* Capture o diagrama RTL do contador.
* Capture a tela de simulação que mostram a contagem (as contagens podem se bem altas, neste caso faça a contagem até 1000)
* Ao escolher a família de FPGAS, escolha o dispositivo FPGA da família '''Cyclone IV E''' do kit e anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo.
* Utilize o procedimento indicado em [[Restringir a frequencia máxima de clock no Quartus]], modificando a frequencia do clock de modo a definir o clock desejado como 50MHz, pois é o clock do kit a ser utilizado
* Utilize o procedimento descrito em [[Como obter o Fmax do projeto no Quartus]]
* Anote a Fmax do projeto, número de elementos lógicos utilizados e o número de pinos utilizados.
* Salve o arquivo QAR com todos os arquivos VHDL, arquivos de simulação tb_XXX.do e wave_XXX.do, e demais necessaários para repetir o projeto.
 
;Passo 1 - Projeto um contador binário sequencial:
* Adapte o código do contador binário para que seja genérico e uso o número de bits indicado para sua equipe.
 
;Passo 2 - Contador Gray:
* Adapte o código do contador Gray para que seja genérico e uso o número de bits indicado para sua equipe.
 
;Passo 3 - Contador em anel:
* Adapte o código do contador em anel para que seja genérico e uso o número de bits indicado para sua equipe.
 
;Passo 4 - Contador Johnson:
* Adapte o código do contador Johnson para que seja genérico e uso o número de bits indicado para sua equipe.
 
;Passo 5 - Contador LFSR:
* Adapte o código do contador LFSR para o número de bits indicado para sua equipe.
* Ver como se pode implementar um contador [https://en.wikipedia.org/wiki/Linear-feedback_shift_register LFSR] de n bits. 
* Consultar [https://users.ece.cmu.edu/~koopman/lfsr/] ou a página 5 de [https://docs.amd.com/v/u/en-US/xapp052] para obter os termos que são usados na realimentação.
 
;Entregas:
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar os projetos de todos os contadores.
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa.  O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão.  A descrição dos procedimentos feita na página wiki não precisa incluída no relatório.
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida.
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
{{collapse bottom}}
 
===AE15 - Timer de Segundos com Mostrador SSD ===
{{collapse top | expand=true| bg=lightyellow | AE15 - Timer de Segundos com Mostrador SSD}}
;Objetivos:
* Desenvolver um timer de segundos, exibindo a contagem de 00 até DU através de dois displays de sete segmentos (SSD).
* Realizar um projeto hierárquico com componentes já utilizados anteriormente.
* Utilizar parâmentros genéricos na instanciação dos componentes para definir o valor total da contagem DU.
* Utilizar sinais ZERAR e CONTAR para controlar o contador BCD.
* Possibilitar a ocultação do número zero na casa da dezena de segundo.
* O projeto deverá ser implementado em FPGA em um dos kits disponíveis no LabSiDi.
 
;PASSO 0 - Contador BCD:
* Adapte o contador BCD ('''contaBCD.vhd''')
:* Baseie-se no contador desenvolvido em aula (faixa 00–99).
:* O clock do contador deverá ser o clock fornecido pelo kit (50MHz => 20ns)
:* São necessárias as seguintes modificações:
::* Adicione entradas: 1) ENABLE para controlar a contagem. 2) ZERAR: zera a contagem. 3) CONTAR: habilita ou desabilita a contagem.
::* Adicione os parâmetros (generics) para limitar a contagem de 00 até DU.
::* Use IF GENERATE para disponibilizar: 1) Um modo com overflow automático (contagem contínua). 2) Um modo com parada ao atingir o valor final (DU).
 
*Simule o contador e verifique que funciona. 
:*Use um CLOCK de 10Hz e um sinal de ENABLE  de 1Hz com duty cycle de 10%
:*Teste o funcionamento das entradas ZERAR e CONTAR.
:*Verifique se os parâmetros genéricos D e U limitam corretamente a contagem.  Teste com D = 2 e U = 3. O contador deve contar de 00 a 23.
:* Verifique se as opções de overflow e parada funcionam.
 
;PASSO 1 - Divisor de Clock:
* Adapte o divisor de clock ('''div_clk.vhd''')
:* Gere um pulso de habilitação (ENABLE_OUT) para o contador a cada 1 segundo, a partir do clock disponível no kit.  O pulso deve durar o período de 1 clock (20ns)
:* Se ainda não tiver, inclua uma entrada de RESET assincrono neste componente.
:* Gere também um sinal de CLOCK_OUT de 1 segundo com duty cycle de 50% para ser conectado a um led externo.
*Simule o divisor de clock e verifique que funciona. 
:*Use um CLOCK de 50Hz e verifique se as saidas CLOCK_OUT e ENABLE_OUT estão corretas
 
;PASSO 2 - Conversor BCD2SSD:
* Projeto o conversor BCD para SSD ('''bcd2ssd.vhd''')
:* Converta o valor de entrada BCD (0 a 9) para o padrão de 7 segmentos.
:* Usando IF GENERATE selecionar o tipo de display: a) Ânodo comum  b) cátodo comum.
:* Inclua uma entrada OCULTA_ZERO para ocultar o zero no display.
*Simule o conversor BCD para SSD e verifique que funciona. 
:*Use na entradas valores BCD de 0 a 9 e verifique se as saidas SSD estão corretas
:*Teste com a opção ânodo comum e cátodo comum.
:*Teste se a entrada OCULTA_ZERO funciona.
 
;PASSO 3 - Entity Top-Level:
* Implemente a entity Top-Level ('''timer_seg.vhd''')
:* Instancie os componentes:
::2x bcd2ssd.vhd → um para as unidades, outro para as dezenas.
::1x contaBCD.vhd → configurado para contar de 00 a 59, com reset automático ao final.
::1x div_clk.vhd → para gerar o sinal de ENABLE de 1 Hz e o clock de 1 sec.
 
<syntaxhighlight lang=vhdl>
entity timer_seg is
    generic (DEZENA  : natural := 5; UNIDADE : natural := 9; FCLOCK : natural := 50);
    port (
        CLOCK50MHz  : in std_logic;
        RESET_PB    : in std_logic;
        CONTAR_SW  : in std_logic;
        ZERAR_PB    : in std_logic;
        LED_1SEC    : out std_logic;
        SSD_DEZENA  : out std_logic_vector(6 downto 0);
        SSD_UNIDADE : out std_logic_vector(6 downto 0));
end entity;
 
Arquitetura sugerida
architecture ifsc of timer_seg is
    -- Sinais internos: BCD_UNIDADE, BCD_DEZENA, ENABLE_1SEC, etc.
    -- Declaração dos componentes usados
begin
    -- Instância do divisor de clock
    -- Instância do contador BCD
    -- Instâncias dos conversores BCD para SSD
end architecture;
</syntaxhighlight>
*O projeto deve ser sincrono, portanto todos os registradores (flip-flops) devem estar conectados ao CLOCK50MHz
*Conecte o RESET_PB a entrada reset dos componentes '''div_clk.vhd''' e '''contaBCD.vhd'''.
*Conecte a saída de ENABLE_OUT ao ENABLE do contador
*Conecte a saída BCD das dezenas a um dos conversores bcd2ssd.vhd e a saída das unidades ao outro.
*O display das dezenas podeve ocultar o zero, enquanto que o display das unidades sempre deve mostrar o zero.
*Simule o timer para contar de 00 a 59 com reinício automático (overflow), e para display de cátodo comum.
*Simule o timer para contar de 00 a 23 com parada, e para display de ânodo comum.
 
;PASSO 4 - Implemetação no Kit FPGA:
Implemente o projeto no FPGA:
* Escolha um dos kits disponíveis no laboratório.
* Configure o projeto para exibir nos dois mostradores HEX (HEX0 e HEX1) ou DISP (DISP0 e DISP1).
* Verifique se o display do kit é ânodo comum ou cátodo comum, e configure o bcd2ssd.vhd corretamente.
* Verifique os clocks disponíveis no kit (Ex.: 50 MHz, 100 MHz), e configure corretamente o parâmetro FCLOCK, para que o ENABLE_1SEC e LED_1SEC estejam com período de 1 segundo.
* Defina as chaves (ou botões) de controle para: CONTAR (SW), ZERAR (PB), RESET (PB).  Verifique se os PUSH BUTTON (PB) são normalmente BAIXOS ou ALTOS.  No segundo caso é necessário incluir um inversor no top-level.
* Configure o parâmetro DU para que a contagem seja de 00 até 59 e depois reinicie automaticamente.
 
;PASSO 5 - Entregas:
*Documentar o experimento em um relatório técnico que contenha no mínimo:
:*Identificação (título, disciplina, data, autores);
:*Introdução;
:*Descrição dos componentes utilizados e do sistema completo. Cada componente deve ser descrito em termos funcionais, e também deve ter uma simulação que demonstre o seu funcinamento.
:*Documente todas as simulações com ondas claras para cada componente e para o sistema completo.
:*Resultados obtidos (com imagens dos itens importantes) e análise dos resultados;
:*Apresente tabelas da pinagem utilizada na configuração do FPGA, número de elementos lógicos usados em cada componente e pelo sistema completo.
:*Conclusão.
*O relatório deve também responder as questões levantadas e mostrar que os objetivos apresentados na introdução foram atendidos.
*O arquivo QAR contendo o projeto com todos os arquivos .vhd .do necessários para repetir o projeto e as simulações
*O arquivo SOF usado na programação do FPGA.
*Se for solicitado disponibilize vídeos demonstrando o funcionamento do timer.
<center> {{#ev:youtube|orjy0GURH_U}} </center>
{{collapse bottom}}
 
===AE16 - Controlador de Semáforo de duas vias  ===
{{collapse top | expand=true| bg=lightyellow | AE16 - Controlador de Semáforo de duas vias}}
;Objetivos:
* Projetar uma Maquina de Estados Finita (FSM) para controlar um semáforo, com timer de segundos em componente externo.
* Reutilizar o timer de segundos (binário)
* Reutilizar o divisor de clock, e gerador de sinal de enable a cada segundo.
* Realizar um projeto hierárquico.
* Realize um projeto sincrono
* Os componentes deve usar um código em dois segmentos, no qual o primeiro segmento realiza a atualização dos registrador, e o segundo segmento realiza a Lógica do Próximo Estado, e as Lógicas de Saída.
* O projeto '''pode''' ser implementado em FPGA em um dos kits disponíveis no LabSiDi, mas '''não é obrigatório'''.
 
;PASSO 0 - Timer de Segundos:
* Adapte o timer de segundos para contar em binário ('''timer_sec.vhd''')
:* O clock do contador deverá ser o clock fornecido pelo kit (50MHz => 20ns)
::* Adicione entradas: 1) ENABLE para controlar a contagem. 2) ZERAR: zera a contagem. 3) CONTAR: habilita ou desabilita a contagem.
::* Adicione os parâmetros (generics) para limitar a contagem de 0 até MAX, onde MAX é o tempo máximo de verde do semáforo.
 
*Simule o contador e verifique se funciona. 
:*Use um CLOCK de 10Hz e um sinal de ENABLE  de 1Hz com duty cycle de 10%
:*Teste o funcionamento das entradas ZERAR e CONTAR.
 
;PASSO 1 - Divisor de Clock:
* Utilize o divisor de clock ('''div_clk.vhd''') da atividade AE15.  Nenhuma adaptação é necessária.
 
;PASSO 2 - FSM do semáforo:
* Projeto da FSM do semáforo  ('''FSM_semaforo.vhd''')
:*Utilize o template fornecido para descrever a FSM representada pelo seguinte diagrama de estados:
{{fig|AE16a|FSM - Controlador semafórico para duas vias  (diagrama de estados)|FSM_Sema2Vias.png|800 px| }}
:* Adicione uma saída Mealy enviar um signal ZERAR o timer que é usado nas transições da FSM.
:* Opcionalmente, você pode enviar um signal ZERAR usando uma saída Moore, que é ativada em 6 estados adicionais inseridos antes de entrar em cada um dos 6 estados da FSM.
 
*Simule a FSM do semáforo e verifique se funciona. 
:*Para testar, é necessário gerar manualmente o sinal de ATIVAR e os valores do timer para verificar o avanço dos estados da FSM
:*Verifique se o sinal de saida ZERAR é ativado corretamente.
:*Mostre claramente a FSM alternando entre AM1 e AM2, e depois faça o semáforo evoluir por 2 ciclos de controle das vias.
 
;PASSO 3 - Entity Top-Level:
* Implemente a entity Top-Level ('''timer_seg.vhd''')
:* Instancie os componentes:
::1x FSM_semaforo.vhd → FSM com saida ZERAR_CNT do tipo Mealy (ou Moore).
::1x timer_sec.vhd → configurado para contar de 00 a 99, sendo reiniciado pelo sinal ZERAR_CNT .
::1x div_clk.vhd → para gerar o sinal de ENABLE de 1 Hz e o clock de 1 sec.
{{fig|AE16b|Diagrama RTL do Controlador semafórico para duas vias |RTL_Sema2Vias.png|800 px| }}
 
<syntaxhighlight lang=vhdl>
entity controlador_semaforo IS
generic (
tAMG : natural := 5; tVD1G : natural := 60; tVD2G : natural := 30;
Nbits_timer :natural := 6;
FCLK : natural := 50; Nbits_clk : natural := 6);
port (
CLK50MHz : in std_logic;
RESET_PB : in std_logic;
ATIVAR_SW : in std_logic;
CONTAR_SW : in std_logic;
LED_1sec : out std_logic;
vm1_LED, vd1_LED, am1_LED, vm2_LED, vd2_LED, am2_LED : out std_logic);
end entity;
 
Arquitetura sugerida
architecture ifsc of controlador_semaforo is
    -- Sinais internos: timer_std, zerar_cnt, ena_1sec, etc.
    -- Declaração dos componentes usados
begin
    -- Instância do divisor de clock
    -- Instância do timer binario de 1 sec
    -- Instância da FSM do semaforo
end architecture;
</syntaxhighlight>
 
*O projeto global deve ser sincrono, portanto todos os registradores (flip-flops) devem estar conectados ao CLOCK50MHz
*Simule o funcionamento da FSM no modo amarelo piscante (ativar = 0).
{{fig|AE16c|Simulação do Controlador semafórico para duas vias  (amarelo piscante)|SIM_Sema2ViasAM1AM2.png|800 px| }}
 
*Simule o funcionamento da FSM no modo normal (ativar = 1), permitindo pelo menos dois ciclos de VERDE nas duas vias controladas.
{{fig|AE16d|Simulação do Controlador semafórico para duas vias  (ciclo verde)|SIM_Sema2ViasVD1VD2.png|800 px| }}
 
;PASSO 4 - Entregas:
*Documentar o experimento em um relatório técnico que contenha no mínimo:
:*Identificação (título, disciplina, data, autores);
:*Introdução;
:*Descrição dos componentes utilizados e do sistema completo. Cada componente deve ser descrito em termos funcionais, e também deve ter uma simulação que demonstre o seu funcionamento.
:*A FSM deve ser descrita usando um diagrama de estados ou um ASM.
:*Nas simulações de FSM é importante destacar a evolução dos estados da FSM.
:*Documente todas as simulações com ondas claras para cada componente e para o sistema completo.
:*Resultados obtidos (com imagens dos itens importantes) e análise dos resultados;
:*Descrever claramente o papel de cada membro da equipe no projeto.  Lembre-se que todos devem ter um papel, e podem ser questionados sobre sua participação.
:*Conclusão.
*O relatório deve também responder as questões levantadas e mostrar que os objetivos apresentados na introdução foram atendidos.
*O arquivo QAR contendo o projeto com todos os arquivos .vhd .do necessários para repetir o projeto e as simulações
{{collapse bottom}}
 
<!--
===AE5 - Controlador de ventoinha ===
{{collapse top | expand=true| bg=lightyellow | AE5 - Controlador de ventoinha}}
;Objetivos:
 
;Materiais auxiliares:
<center>[https://drive.google.com/file/d/1VhZLehwB_ijpc0V14Wg_of998NUMeAvw/view?usp=drive_link Datasheet da ventoinha ADDA AD0912UX-A7BGL]</center>
{{fig|AE5.a|Diagrama elétrico da ventoinha| DiagramaVentoinha.png| 600 px |https://i1.wp.com/nets-nuts.com.br/wp-content/uploads/2015/12/cooler_pwm2. jpg}}
{{fig|AE5.a|Conexão elétrica da ventoinha| FiosVentoinha.png| 600 px |https://hardzone.es/tutoriales/mantenimiento/ventiladores-3-4-pines-diferencias/}}
 
{{collapse bottom}}
<!--
===AE3 - Laboratório de programação de FPGA - Relógio HHMMSS===
{{collapse top | bg=lightyellow | AE3 - Laboratório de programação de FPGA - Relógio HHMMSS}}
;Objetivos:
*Desenvolver sistemas utilizando componentes já desenvolvidos.
*Apreender a instanciar componentes e conectá-los com sinais.
*Realizar um  projeto hierárquico.
 
;Consulte:
*[[Preparando para gravar o circuito lógico no FPGA]]
*[[Interfaces de entrada e saída da DE2-115]]
*[[Display de 7 segmentos]]
 
;Passo 1 - Projeto do Relogio_HHMMSS:
*Projete um relógio para indicar hora (HH), minuto (MM) e segundo (SS), mostrando as unidades e dezenas em 6 [[Display de 7 segmentos]], usando os seguintes componentes: 1) Divisor de clock para obter um sinal de período de 1 segundo. ('''div_clk'''); 2) Contador configurável BCD de 00 a 99 ('''contador_bcd''') 3) Conversor de BCD para SSD, com configuração de apagamento do zero e tipo de ligação dos segmentos.
 
*Componente 1 - Divisor de Clock, com o valor da divisão configurável pelo parâmetro '''fclk2'''.  O sinal de saída será usado como "enable" ou "clock" a cada 1 segundo para o componente '''contador_bcd'''.
<syntaxhighlight lang=vhdl>
component div_clk is
generic (fclk2 : natural := 50);      -- frequencia para simulacao
port (
clk_in : in std_logic;
rst : in std_logic;
clk_out : out std_logic
);
end component;
 
</syntaxhighlight>
 
*Componente 2 - Contador de 00 a 99 com saída em BCD, (pode ser um contador em BCD (ou um contador binário + conversor bin2bcd). O valor final deve ser configurável pelos parâmetros '''max_dezena e max_unidade'''
<syntaxhighlight lang=vhdl>
component contador_bcd is
generic (max_dezena : natural := 5; max_unidade : natural := 9);
port (
  clk: in std_logic;
  rst: in std_logic;
  fim: out std_logic;
  bcd_unidade, bcd_dezena : out std_logic_vector(3 downto 0)
);
end component;
</syntaxhighlight>
 
Para esse contador pode ser usado o desenvolvido em aula, mas ele precisa ser modificado para permitir que o ''clock'' seja síncrono em todos os ''flip-flops''.  Assim é necessário usar um sinal de '''enable_in''' para habilitar a contagem durante um período de clock.  Também será necessário gerar o sinal de '''enable_out''' para habilitar a contagem do próximo contador.
 
*Componente 3 - Conversor de BCD para SSD, com um parâmetro configurável '''ac_ccn''' para selecionar o tipo de mostrador (Anodo Comum / Catodo Comum).
<syntaxhighlight lang=vhdl>
component bcd2ssd is
generic (ac_ccn : natural := 0);  -- 1 para mostrador de anodo comum, 0 para mostrador de catodo comum
port (
bcd_in :  in std_logic_vector(3 downto 0);
z_opc:    in std_logic;  -- 1 o zero é mostrado, 0 - o zero é apagado.
ssd_out : out std_logic_vector(6 downto 0)
);
end component;
</syntaxhighlight>
 
*O valor '''ac_ccn''' será utilizado para configurar o circuito de modo a acender os segmentos com ALTO para display de catodo comum (ac_ccn=0), ou BAIXO para display de anodo comum (ac_ccn=1).
*A entrada '''zero_option''' pode ser usada para apagar a dezena da HH, MM e SS.
 
* '''Opção 1''' - Na entidade TOP LEVEL, podem  ser instanciados os seguintes componentes: um '''div_clk'''; três '''contador_bcd''' e seis '''bcd2ssd'''.  Além disso, se necessário podem ser inseridos os inversores necessários para adequar ao hardware do kit DE2-115.
 
* '''Opção 2''' -  Se quiser, você pode criar um componente com um '''contador_bcd''' e dois '''bcd2ssd''' e replicar 3 vezes esse componente na entidade TOP LEVEL.
 
*'''IMPORTANTE''': É necessário incluir um RESET no circuito sequencial e também uma entrada de enable no contador.
 
<syntaxhighlight lang=vhdl>
entity relogio_HHMMSS IS
        -- O valor do fclk2 corresponde a metade do periodo do clock de entrada em Hz
generic (fclk2 : natural := 50);  -- ao simular o circuito utilize um valor baixo para acelerar a simulaçao
        -- generic (fclk2 : natural := 25000000);  -- ao implementar no hardware use o valor do clock em Hz
port
(
clk_50MHz_kit: in  STD_LOGIC;
rst_SW: in STD_LOGIC;  -- use uma chave deslizante para essa função RESET
stop_SW: in STD_LOGIC;  -- use uma chave deslizante para essa função PARAR e CONTINUAR
z_opc_SW: in STD_LOGIC;  -- use uma chave deslizante para essa função apagar o zero das dezenas
ssd_DS, ssd_DM, ssd_DH: out  STD_LOGIC_VECTOR(6 downto 0);
ssd_US, ssd_UM, ssd_UH: out  STD_LOGIC_VECTOR(6 downto 0)
);
end entity;
</syntaxhighlight>
 
{{fig|AE2.a|RTL do Relógio Digital de 24 horas| Rtl_relogio24h.png| 800 px |}}
 
;Passo 2 - Simule os componentes e o relógio completo:
 
* Efetue a simulação funcional do '''div_clock''', definindo a entrada de '''clk_in''' como um sinal de 100 Hz, e realizando a simulação para produzir um clk_out de 1Hz.  Certifique-se que a duração do sinal alto é de apenas 1 período do sinal de clk_in.
 
* Efetue a simulação funcional do '''contador_bcd''' fazendo a contagem de 00 a 99 e também de 00 a DU, onde DU é um valor qualquer configurável pelo genéricos D e U. O contador só deverá contar se o '''enable_in''' estiver ALTO.  Durante a mudança de DU para 00 o '''enable_out''' deverá ir para ALTO. Na simulação use um clock de 1 segundo,  e faça uma simulação de pelo menos 120 segundos.
 
* Efetue a simulação do '''bcd2ssd''' testando o circuito para as estradas bcd_in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Para os valores inválidos de entrada (10, 11, 12, 13, 14, 15), a saída deve mostrar "E" (de erro).
 
* Nas simulações dos circuitos sequencias é necessário iniciar o circuito com um RESET de 10 ps.
 
* Realize a simulação do relógio completo '''relogio_HHMMSS''' durante 48 horas.  Para esta simulação é importante configurar o divisor de clock para realizar uma divisão com um fator menor que aquele a ser usado no circuito final (veja o comentário no código acima).
 
{{fig|AE4.b|Simulação funcional do Relógio Digital de 24 horas| Sim_relogio24h.png| 800 px |}}
 
{{fig|AE4.c|Simulação funcional do Relógio Digital de 24 horas - detalhe enable 1sec| Sim_relogio24h_enable.png| 800 px |}}
 
;Passo 3 - Implemente o relógio no kit DE2-115:
 
*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]].  Neste caso iremos usar o kit DE2-115 da TERASIC, pois precisamos de 6 mostradores de 7 segmentos.
 
* Analise no diagrama esquemático como funcionam as chaves e também o mostrador de sete segmentos. Note que no projeto o signal RST foi descrito como normalmente ALTO, por isso dependendo da chave que usar pode ser necessário acrescentar um inversor neste sinal para que funcione corretamente. O [[Display de 7 segmentos]] da DE2-115 é do tipo anodo comum (aplicando um nível lógico '0' no pino correspondente fará com que o segmento acenda, enquanto a aplicação do nível lógico '1' fará com com que o segmento apague). 
 
*Anote a pinagem que será utilizada para conectar o circuito projetado no FPGA aos circuitos externos do kit (mostradores, chaves e leds).
 
{{collapse top| definição dos pinos}}
{| class="wikitable sortable" style="text-align:center;"
|- style="font-weight:bold; background-color:#c0c0c0;"
! To
! Direction
! Location
|-
| clk50MHz
| Input
| PIN_Y2
|-
| clk_1sec_LED
| Output
| PIN_F17
|-
| rst_sw
| Input
| PIN_AB28
|-
| ssd_DHH[0]
| Output
| PIN_AD17
|-
| ssd_DHH[1]
| Output
| PIN_AE17
|-
| ssd_DHH[2]
| Output
| PIN_AG17
|-
| ssd_DHH[3]
| Output
| PIN_AH17
|-
| ssd_DHH[4]
| Output
| PIN_AF17
|-
| ssd_DHH[5]
| Output
| PIN_AG18
|-
| ssd_DHH[6]
| Output
| PIN_AA14
|-
| ssd_DMM[0]
| Output
|
|-
| ssd_DMM[1]
| Output
|
|-
| ssd_DMM[2]
| Output
|
|-
| ssd_DMM[3]
| Output
|
|-
| ssd_DMM[4]
| Output
|
|-
| ssd_DMM[5]
| Output
|
|-
| ssd_DMM[6]
| Output
|
|-
| ssd_DSS[0]
| Output
|
|-
| ssd_DSS[1]
| Output
|
|-
| ssd_DSS[2]
| Output
|
|-
| ssd_DSS[3]
| Output
|
|-
| ssd_DSS[4]
| Output
|
|-
| ssd_DSS[5]
| Output
|
|-
| ssd_DSS[6]
| Output
|
|-
| ssd_UHH[0]
| Output
|
|-
| ssd_UHH[1]
| Output
|
|-
| ssd_UHH[2]
| Output
|
|-
| ssd_UHH[3]
| Output
|
|-
| ssd_UHH[4]
| Output
|
|-
| ssd_UHH[5]
| Output
|
|-
| ssd_UHH[6]
| Output
|
|-
| ssd_UMM[0]
| Output
|
|-
| ssd_UMM[1]
| Output
|
|-
| ssd_UMM[2]
| Output
|
|-
| ssd_UMM[3]
| Output
|
|-
| ssd_UMM[4]
| Output
|
|-
| ssd_UMM[5]
| Output
|
|-
| ssd_UMM[6]
| Output
|
|-
| ssd_USS[0]
| Output
|
|-
| ssd_USS[1]
| Output
|
|-
| ssd_USS[2]
| Output
|
|-
| ssd_USS[3]
| Output
|
|-
| ssd_USS[4]
| Output
|
|-
| ssd_USS[5]
| Output
|
|-
| ssd_USS[6]
| Output
|
|}
{{collapse bottom}}
 
*Dica para testar o relógio sem aguardar 24 horas. Acelere o clock de entrada do contador de segundos de 60 (ou 1440 vezes), com isso o sistema realizará a contagem de 00:00:00 a 23:59:59 em 24 minutos (ou 1 minuto).
 
;Passo 4 - Entregas:
*Documentar o experimento em um relatório técnico que contenha no mínimo:
:*identificação (título, disciplina, data, autores);
:*introdução;
:*Descrição dos componentes utilizados e do sistema completo. Cada componente deve ser descrito em termos funcionais, e também deve ter uma simulação que demonstre o seu funcinamento.
:*resultados obtidos (com imagens dos itens importantes) e análise dos resultados;
:*apresente tabelas da pinagem utilizada na configuração do FPGA, número de elementos lógicos usados em cada componente e pelo sistema completo.
:*conclusão.
:*apêndice (se desejar pode ser disponibilizados vídeos do funcionamento do circuito
 
*O relatório deve também responder as questões levantadas e mostrar que os objetivos apresentados na introdução foram atendidos.
 
*O arquivo QAR contendo o projeto
*Os arquivos para simulação (DO) necessárias para simular o sistema '''relogio_HHMMSS''' e seus componentes.
*O arquivo SOF usado na programação do FPGA.
<center> {{#ev:youtube|orjy0GURH_U}} </center>
{{collapse bottom}}
 
===AE3 -  Projeto de uma FSM para controle semafórico===
{{collapse top |  bg=lightyellow | AE3 -  Projeto de uma FSM para controle semafórico}}
;Objetivos:
*Aplicar o conhecimento de FSM no projeto de um controle semafórico.
*Obter a especificação do projeto pela observação do funcionamento do equipamento atual
*Fazer a simulação funcional dos componentes individuais e do controle semafórico
*Utilizar saídas do tipo Moore (para os focos luminosos) e Meally (inicialização das temporizações)
*O projeto será desenvolvido por equipes de até 2 estudantes, e cada equipe deverá escolher um cruzamento de vias que tenha além de dois grupos semafóricos progressivo, também pelo menos um semáforo de pedestre.
*Cada equipe deverá sugerir e implementar uma melhoria em relação ao equipamento atual instalado no cruzamento das vias. Um dos objetivos do projeto é buscar por soluções semafóricas inovadoras, incluindo aprimoramentos específicos para o período noturno ou economia de energia. O objetivo é proporcionar uma experiência mais segura e visível para veículos e pedestres ao cruzar vias durante o dia e a noite.
 
Como material auxiliar se sugere consultar o  [[media:Manual_Brasileiro_de_Sinalização_de_trânsito_VOLUME_V.pdf | Manual Brasileiro de Sinalização de trânsito: VOLUME V - Sinalização Semafórica]] do CONTRAN. Outro material resumido sobre o tema  pode ser consultado em [https://ecivilufes.files.wordpress.com/2013/07/aula9.pdf Sinalização semafórica: definições] - Universidade Presbiteriana Mackenzie
 
;Atividades:
*'''PASSO 1 -''' fazer o levantamento do semáforo selecionado para o projeto.
:*Selecionar um semáforo e obter a imagem das vias e da área de conflito que é controlada pelo semáforo.
{{fig|AE3.1|Imagem aérea do Google do cruzamento Shibuya Crossing, em Tóquio, Japão |Shibuya_Crossing_Aerea.png|900 px|Google maps|[https://www.google.com.br/maps/@35.6596989,139.700302,150m/data=!3m1!1e3?entry=ttu&g_ep=EgoyMDI1MDIwNS4xIKXMDSoJLDEwMjExMjM0SAFQAw%3D%3D]}}
:*Fazer um croqui das vias e passagens de pedestre dessa área.
{{fig|AE3.2|Diagrama do cruzamento Shibuya Crossing |Shibuya_Crossing_ruas.png|900 px|Google Maps| [https://www.google.com.br/maps/@35.6595402,139.7003597,19.5z?entry=ttu&g_ep=EgoyMDI1MDIwNS4xIKXMDSoJLDEwMjExMjM0SAFQAw%3D%3D]}}
:*Elaborar um rascunho ou foto dos semáforos existentes
{{fig|AE3.3|Imagem do Google Street do cruzamento Shibuya Crossing |Shibuya_Crossing_Street.png|900 px| Google Street | [https://www.google.com.br/maps/@35.6595077,139.7001449,3a,90y,104.81h,109.96t/data=!3m7!1e1!3m5!1sN731RghU_E2dIIVGCaKDHQ!2e0!6shttps:%2F%2Fstreetviewpixels-pa.googleapis.com%2Fv1%2Fthumbnail%3Fcb_client%3Dmaps_sv.tactile%26w%3D900%26h%3D600%26pitch%3D-19.961007189407056%26panoid%3DN731RghU_E2dIIVGCaKDHQ%26yaw%3D104.80587305998158!7i16384!8i8192?entry=ttu&g_ep=EgoyMDI1MDIwNS4xIKXMDSoJLDEwMjExMjM0SAFQAw%3D%3D ]}}
:*Elaborar um rascunho do '''diagrama de estágios''' [https://wiki.sj.ifsc.edu.br/images/9/97/Manual_Brasileiro_de_Sinaliza%C3%A7%C3%A3o_de_tr%C3%A2nsito_VOLUME_V.pdf#page=71 pag. 72] e [https://wiki.sj.ifsc.edu.br/images/9/97/Manual_Brasileiro_de_Sinaliza%C3%A7%C3%A3o_de_tr%C3%A2nsito_VOLUME_V.pdf#page=149 pag. 150]
:*Medir os tempos de ciclo do semáforo.
:*Elaborar um rascunho do '''diagrama de intervalos luminosos'''  (Diagrama de barras). [https://wiki.sj.ifsc.edu.br/images/9/97/Manual_Brasileiro_de_Sinaliza%C3%A7%C3%A3o_de_tr%C3%A2nsito_VOLUME_V.pdf#page=71 pag.72] e [https://wiki.sj.ifsc.edu.br/images/9/97/Manual_Brasileiro_de_Sinaliza%C3%A7%C3%A3o_de_tr%C3%A2nsito_VOLUME_V.pdf#page=189 pag. 190]
 
*'''PASSO 2 -''' Projetar a FSM do controlador de semáforo
:*Desenhar o diagrama de transições da FSM
:*Desenhar o ASM
:*Escrever o código em VHDL da FSM
:*Fazer a '''Análise e Síntese''' no Quartus
:*Observar e analisar o RTL e o diagrama de estados no Quartus
:*Verificar o número de elementos lógicos usados
:*Fazer Timing Analysis e anotar as FMax
:*Fazer a simulação funcional, permitindo um (ou dois) ciclos completo do controlador semafórico (Dica utilize cores verde, vermelha e amarela para facilitar a visualização dos semáforos).
 
*'''PASSO 3 - ''' Implementar um sistema hierárquico para o controlador
:*Para a geração do tempo do controlador de semáforo utilize pelo menos um componente para o contador de segundos (binário ou BCD).
:*O controlador semafórico deve ser um componente separado
:*Se preferir utilize também um componente para o divisor de clock para gerar o sinal de 1 segundo a partir do clock de 50MHz, não esqueça de usar um divisor menor na simulação (sugestão 5)
:*O Top Level do projeto deve conter apenas a instanciação dos componentes do projeto.
:*Observar e analisar o RTL e o diagrama de estados no Quartus
:*Verificar o número de elementos lógicos usados e o FMax
:*Fazer a simulação funcional de um ciclo completo do controlador semafórico.
 
;Entregas:
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar e simular o projeto.  O QAR deve conter todos os arquivos .vhd e arquivos .do dos componentes e do top level.
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa.  O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão.  A descrição dos procedimentos feita na página wiki não precisa incluída no relatório.  Dados numéricos devem ser apresentados na forma gráfica ou tabela, jamais como imagem capturada de tela.
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida.
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
{{collapse bottom}}
 
===AE4 - Comparação de Hardware projetado por FSMD e Dataflow===
{{collapse top | bg=lightyellow | AE4 - Comparação de Hardware projetado por FSMD e Dataflow}}
;Objetivos:
*Analisar o funcionamento de diferentes versões de FSMD para multiplicação de dois números.
*Analisar o funcionamento de diferentes versões de algoritmos dataflow para  multiplicação de dois números.
*Fazer a simulação funcional de várias FSMDs e comparar com a implentação estruturada em fluxo de dados.
*Analisar a influência do número de bits sobre o número de elementos lógicos, frequencia máxima e tempo total de cálculo.
*O projeto será desenvolvido por equipes de até 2 estudantes.
*Cada exipe deverá realizar a simulação com pelo menos duas multiplicações, uma com um fator baixo (< 5) e outra com ambos fatores > 10.  As equipes devem informar de antemão os valores que irão utilizar, e não poderão usar valores iguais as demais equipes.
 
;Atividades:
*'''PASSO 1 -''' Entender e testar os códigos das Listing (L11.1 ou L11.2 ou L11.3), L11.5, L11.6, L11.7 e L11.8 de  <ref name="CHU2006"/>.
::Entre as L11.1, L11.2 e L11.3, escolha apenas uma delas para os testes. A L11.4 fica de fora pois conter erro.
:*Realize a '''Analyses e Synthesis''', '''Fitter''' e '''Timing Analysis''' de cada versão
:*Obtenha os valores de frequência máxima ('''Fmax''') e número de elementos lógicos ('''Nel''') de cada versão
:*Efetue a simulação utilizando um clock de 1 ns com pelo menos duas multiplicações, uma com um fator baixo (< 5) e outra com ambos fatores > 10.  Essa etapa ajuda a determinar o número de clocks
:*Meça o número de clocks ('''Nclk''') necessário para realizar a operação, e calcule o tempo total ('''Tcal''') para realizar a operação.
 
*'''PASSO 2 -''' Análise da variação do número de bits
:*Altere o código para que funcione para um número genérico de bits. 
::Dica:  Para gerar um vetor de N zeros, crie uma constante e utilize a constante no código.
constant zeros : std_logic_vector(N-1 downto 0) := (others => '0');
:*Repita o PASSO 1 variando o tamanho do multiplicador para 4, 8, 16, 32, 64 bits.
::'''Nota:''' A simulação com 32 e 64 bits da (L11.1 ou L11.2 ou 11.3) ficará muito longa, e por isso não deve ser feita.  Nestes casos estime o número de clocks a partir dos fatores multiplicadores.
:*Anote em uma tabela os valores '''Fmax, Nel, Nclk, Tcal''' para cada uma das versões e número de bits
:*Guarde a imagem do circuito RTL para 4 bits obtido em cada versão, incluindo o diagrama de estado da FSM se for o caso.
:*Ao efetuar a simulação use um fator alto que seja proporcional ao número de bits.  Ou seja para 8 bits use um número maior que 128 = 2^(8-1).
 
*'''PASSO 3 -''' Análise de um multiplicador direto
:*Escreva um código de um multiplicador que utilize diretamente a função de multiplicação
<syntaxhighlight lang=vhdl>
r <= a * b;
</syntaxhighlight>
:*Também insira registradores nas duas entradas de dados e também na saída, de modo que fique semelhante ao destacado na figura em contorno vermelho.
{{fig|AE4.1|RTL do multiplicador direto|RTL_multiplicador_direto.png|900 px||}}
:*Faça toda a análise para  4, 8, 16, 32, 64 bits.
:*Anote em uma tabela os valores '''Fmax, Nel, Nclk, Tcal''' para cada número de bits
:*Guarde a imagem do circuito RTL para 4 bits obtido.
:*Ao efetuar a simulação use os mesmos fator utilizados no PASSO 2 para cada tamanho do multiplicador.
 
*'''PASSO 4 -''' Análise de um multiplicador por somas sucessivas
:*Escreva um código de um multiplicador que efetue somas sucessivas para efetuar a multiplicação
<syntaxhighlight lang=vhdl>
-- declare o sinal aux como um vetor de dados do tipo unsigned
type uns_vector is array (0 to 2**W) of unsigned(2*W-1 downto 0);
signal aux : uns_vector;
 
-- utilize o vetor aux para guardar as sucessivas somas da entrada a_in
-- utilize a entrada b_in para decidir qual dos somas correspode ao resultado.
-- NOTA: este código é muito ineficiente, e está apenas sendo usado para comparar com os códigos desenvolvidos com a metodologia RT;
aux(0) <= to_unsigned(0,2*W);
l1: for k in 0 to 2**W-1 generate
aux(k+1) <= aux(k) + resize(unsigned(a_in),2*W);
end generate;
r <= std_logic_vector(aux(to_integer(unsigned(b_in))));
</syntaxhighlight>
:*Também insira registradores nas duas entradas de dados e também na saída, de modo que fique semelhante ao destacado na figura em contorno vermelho.
{{fig|AE4.2|RTL do multiplicador por somas sucessivas|RTL_multiplicador_somas.png|900 px||}}
:*Faça toda a análise para  4 e  8 bits apenas.
:*Anote em uma tabela os valores '''Fmax, Nel, Nclk, Tcal''' para cada número de bits
:*Guarde a imagem do circuito RTL para 4 bits obtido.
:*Ao efetuar a simulação use os mesmos fator utilizados no PASSO 2 para cada tamanho do multiplicador.
 
;Entregas:
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar e simular o projeto.  O QAR deve conter todos os arquivos .vhd e arquivos .do.
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa.  O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão.  A descrição dos procedimentos feita na página wiki não precisa incluída no relatório.  Dados numéricos devem ser apresentados na forma gráfica ou tabela, jamais como imagem capturada de tela.
#Faça uma extensa análise sobre o tempo de cálculo x áreas que o circuito ocupa no FPGA para as diferentes versões.  Faça a análise para os diferentes tamnhos do barramento de entrada e saída.
#Sugira qual circuito utilizaria em diferentes situações e quais jamais utilizaria. 
#Escreva uma boa conclusão sobre isso
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida.
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
{{collapse bottom}}
 
===AE2 -  Estudando uma FIFO===
{{collapse top | expand=true | bg=lightyellow | AE2 -  Estudando uma FIFO}}
;Objetivos:
*Conhecer um file register, controlador de FIFO e uma FIFO completa
*Analisar o desempenho (Fmax) e área ocupada pelo circuito usando diferentes versões de implementação
*Construir uma FIFO usando como componentes um file register e um controlador de FIFO
*Fazer a simulação funcional dos componentes individuais e da FIFO
 
;Atividades:
*'''PASSO 1 -''' Código do Register File
:*Use o código disponibilizado no Moodle
:*Fazer  a Análise e Síntese desse código  
:*Fazer  a Análise e Síntese desse código  
:*Observar o RTL
:*Observar o RTL
Linha 1 303: Linha 3 769:
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
{{collapse bottom}}
{{collapse bottom}}
-->


==Referências Bibliográficas:==
==Referências Bibliográficas:==
<references/>
<references/>
Será que uma boa parte do que fazemos com calculo digital será analógico no futuro? [https://www.youtube.com/watch?v=GVsUOuSjvcg Future Computers Will Be Radically Different (Analog Computing)]
{{ENGTELECO}}
{{ENGTELECO}}

Edição atual tal como às 11h22min de 11 de agosto de 2025

1 Registro on-line das aulas

1.1 Unidade 1 - Aula inicial, Introdução a disciplina

  • 1 ENCONTRO
Unidade 1 - Aula inicial, Introdução a disciplina
Encontro 1 (12 ago.)
  • A página da UC contém os materiais que não alteram entre semestre.
  • Relação com as outras UCs do Eixo Sistemas Computacionais (Marrom). Ver grafo do curriculo
  • ELD129002 - ELETRÔNICA DIGITAL I (ELD1): Sistema de numeração e códigos. Lógica booleana. Circuitos combinacionais. Circuitos aritméticos. Linguagem de descrição de hardware. Implementação e teste de circuitos digitais. Projeto de circuitos lógicos.
  • ELD129003 - ELETRÔNICA DIGITAL II (ELD2): Dispositivos lógicos programáveis. Circuitos sequenciais. Metodologia síncrona. Projeto hierárquico e parametrizado. Máquinas de estados finita. Register Transfer Methodology. Teste de circuitos digitais. Implementação em FPGA. Introdução a Linguagem de Descrição de Hardware.
  • AOC129004 - ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES (AOC): Introdução à Arquitetura Computadores. Linguagem Assembly. Linguagem de Máquina. Programação Assembly. Modos de Endereçamento. Processo de compilação e carga de um programa. Introdução à Organização de Computadores. Organização Monociclo e Multiciclo. Pipeline. Memória e Sistema de E/S.
  • MIC129007 - MICROCONTROLADORES (MIC): Introdução a Microcontroladores e Aplicações. Arquitetura de um microcontrolador. Pilha e Subrotinas. Interrupção. Contadores e Temporizadores. Interface com Periféricos. Programação em alto nível (ex.: C, C++ e RUST) para Microcontroladores: Mapeamento de tipos e estruturas de alto nível para sistemas com recursos limitados. Projeto de hardware e firmware com microcontroladores.
  • STE129008 - STE - SISTEMAS EMBARCADOS (STE): Conceitos em Sistemas Embarcados. Metodologia de Desenvolvimento de Sistemas Embarcados. Sistemas Operacionais para Sistemas Embarcados. Ferramentas de desenvolvimento e depuração. Barramentos e dispositivos de acesso a redes. Desenvolvimento de Projeto.
  • Nesta página está o Registro diário dos encontros e avaliações.
  • A entrega de atividades e avaliações será através da plataforma Moodle. A inscrição dos alunos é automática a partir do SIGAA.
  • Para a comunicação entre professor-aluno, além dos avisos no SIGAA, utilizaremos o chat institucional. A princípio todos os alunos já estão previamente cadastrados pelo seu email institucional. Confiram enviando uma mensagem de apresentação.
  • Utilizaremos durante as aulas algumas ferramentas computacionas como o site do Falstad para entender circuitos digitais e fazer simulações básicas.
  • Também utilizaremos os softwares Quartus Light e ModelSim instalados nas maquinas do laboratório para praticar a parte de programação de hardware (descrição de hardware). Esses softwares também podem ser usados através da Nuvem do IFSC..
  • Para a prática de implementação dos circitos em dispositivos lógicos utilizaremos os kits de FPGA disponíveis no LabSiDi. Ver User Manual da DE2-115, e Manual do Usuário da Mercúrio IV.
LER PARA O PRÓXIMO ENCONTRO

1.2 Unidade REV - PRIMEIRO CONTATO COM VHDL

  • 5 ENCONTROS
Unidade REV - PRIMEIRO CONTATO COM VHDL

1.3 Unidade 2 - Dispositivos Lógicos Programáveis

  • 5 ENCONTROS
Unidade 2 - Dispositivos Lógicos Programáveis

1.4 Unidade 3 - Circuitos sequenciais (Implementação com HDL)

  • 18 ENCONTROS
Unidade 3 - Circuitos sequenciais (Implementação com HDL)

1.5 Unidade 4 - Maquinas de Estado Finitas

  • 5 ENCONTROS
Unidade 4 - Maquinas de Estado Finitas

1.6 Unidade 5 - Metodologia RT (Register Transfer)

  • 7 ENCONTROS
Unidade 5 - Metodologia RT (Register Transfer)

2 Avaliações

Durante o semestre serão realizadas 2 avaliações e várias atividades feitas extra classe.

Data das avaliações
  • A1 : Avaliação A1 (peso 35) XX/2025
  • A2 : Avaliação A2 (peso 45) XX/2025
  • AEs : Média ponderada das AEs (peso 20)
  • R1 : Recuperação de A1 : XX/2025
  • R2 : Recuperação de A2 : XX/2025
  • Folha de consulta de VHDL


3 Atividade extra-classe (AE)

A média ponderada das atividades extra-classe será considerada no cálculo do conceito final da UC. A entrega das mesmas será feita pelo Moodle, e cada dia de atraso irá descontar 0,2 na nota da atividade. Muitas dessas atividades também geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN. Para os BÔNUS só serão considerados projetos entregues no prazo.

4 Referências Bibliográficas:

Será que uma boa parte do que fazemos com calculo digital será analógico no futuro? Future Computers Will Be Radically Different (Analog Computing)

Curso de Engenharia de Telecomunicações