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)
 
(215 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 2: Linha 2:
===Unidade 1 - Aula inicial, Introdução a disciplina===
===Unidade 1 - Aula inicial, Introdução a disciplina===
* 1 ENCONTRO
* 1 ENCONTRO
{{collapse top | Unidade 1 - Aula inicial, Introdução a disciplina}}
{{collapse top | expand=true | Unidade 1 - Aula inicial, Introdução a disciplina}}


;Encontro 1 (17 set):
;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 (19 set):
* 5 ENCONTROS
{{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)]
* [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)]


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 (24 set):
;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]
 
*Usando o tipo '''integer'''
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'''.


;Encontro 4 (26 set):
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.
;[[Como arquivar um projeto]]:


;Conhecer instruções WHEN_ELSE, WITH_SELECT, CONFIGURATION:
<syntaxhighlight lang=vhdl>
entity somador is
port (
a, b : in integer;  
s : out integer;
end entity;


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).
architecture ifsc of somador is
begin
s <= a + b;
end architecture;
</syntaxhighlight>


{{collapse top | Mux2x1}}
{{fig|4.1|Código RTL do somador com tipo integer sem range| RTL_somadorv1.png| 300 px |}}
A tabela verdade que descreve um MUX2:1 é mostrada abaixo:
{{fig|4.2|Technology Map do somador com tipo integer sem range| TM_somadorv1.png| 1000 px |}}
<center>
 
{| class="wikitable" style="text-align:center;"
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.
|- style="font-weight:bold;"
 
! X1
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.
! X0
 
! Sel
<syntaxhighlight lang=vhdl>
! style="background-color:#c0c0c0;" | Y
entity somador is
|-
port (
| 0
a, b : in integer range 0  to 15;  
| 0
s : out integer range 0  to 15);
| 0
end entity;
| style="background-color:#c0c0c0;" | 0
 
|-
architecture ifsc of somador is
| 0
begin
| 0
s <= a + b;
| 1
end architecture;
| style="background-color:#c0c0c0;" | 0
</syntaxhighlight>
|-
 
| 0
{{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 |}}
| 0
 
| style="background-color:#c0c0c0;" | 1
Para fazer uma subtração, basta trocar o operador "+" pelo "-", e o compilador irá implementar um subtrator realizando o complemento 2 da entrada b.
|-
 
| 0
<syntaxhighlight lang=vhdl>
| 1
entity subtrator is
| 1
port (
| style="background-color:#c0c0c0;" | 0
a, b : in integer range 0  to 15;  
|-
s : out integer range 0 to 15);
| 1
end entity;
| 0
 
| 0
architecture ifsc of subtrator is
| style="background-color:#c0c0c0;" | 0
begin
|-
s <= a - b;
| 1
end architecture;
| 0
</syntaxhighlight>
| 1
 
| style="background-color:#c0c0c0;" | 1
{{fig|4.5|Código RTL do subtrator com tipo integer com range| RTL_subtratorv1.png| 300 px |}}
|-
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.
| 0
| style="background-color:#c0c0c0;" | 1
|-
| 1
| 1
| 1
| style="background-color:#c0c0c0;" | 1
|}
</center>


O MUX2:1 também pode ser representado de forma resumida por:
<syntaxhighlight lang=vhdl>
<center>
entity incrementador is
{| class="wikitable" style="text-align:center;"
port (
|- style="font-weight:bold;"
a : in integer range 0  to 15;  
! X1
inc : out integer range 0 to 15);
! X0
end entity;
! 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:
architecture ifsc of incrementador is
begin
inc <=  a + 1;
end architecture;
</syntaxhighlight>


{{fig|4.6|Código RTL do incrementador com tipo integer com range| RTL_incrementadorv1.png| 300 px |}}


<math> Y =  \overline{Sel} . X0 + Sel . X1 </math>
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.


Onde Y é a saída; Sel é o sinal de seleção; X0 e X1 são as entradas.
{{collapse bottom}}


{{collapse top | expand=false |Mux4x1}}
Para fazer o decrementador, um dos fatores do somador é substituído por '-1' e o compilador irá implementar um circuito decrementador.
O MUX4:1 pode ser representado de forma resumida pela tabela verdade:


<center>
<syntaxhighlight lang=vhdl>
{| class="wikitable" style="text-align:center;"
entity decrementador is
|- style="font-weight:bold;"
port (
! colspan="4" | Entradas
a : in integer range 0  to 15;  
! colspan="2" | Seleção
dec : out integer range 0  to 15);
! Saída
end entity;
|- style="font-weight:bold;"
 
| X3
architecture ifsc of decrementador is
| X2
begin
| X1
dec <= a - 1;
| X0
end architecture;
| Sel1
</syntaxhighlight>
| Sel0
 
| style="background-color:#c0c0c0;" | Y
{{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.
| -
 
| X0
<syntaxhighlight lang=vhdl>
| 0
entity multiplicador is
| 0
port (
| style="background-color:#c0c0c0;" | X0
a, b : in integer range 0 to 15;
|-
s : out integer range 0 to 15*15);
| -
end entity;
| -
 
| X1
architecture ifsc of multiplicador is
| -
begin
| 0
s <=  a * b;
| 1
end architecture;
| style="background-color:#c0c0c0;" | X1
</syntaxhighlight>
|-
 
| -
{{fig|4.6|Código RTL do multiplicador com tipo integer com range| RTL_multiplicadorv1.png| 300 px |}}
| X2
 
| -
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.
| -
 
| 1
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.
| 0
 
| style="background-color:#c0c0c0;" | X2
<syntaxhighlight lang=vhdl>
|-
entity divisor is
| X3
port (
| -
dividendo : in integer range 0  to 15;
| -
divisor : in integer range 0  to 3;
| -
quociente : out integer range 0  to 15;
| 1
resto : out integer range 0  to 3
| 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>
end entity;
{{collapse bottom}}
 
Dada a função booleana do MUX4:1 é simples para descreve-lo em VHDL utilizando apenas operadores lógicos.
 
<syntaxhighlight lang=vhdl>
entity mux4x1 is
port
(
-- Input ports
X: in  bit_vector (3 downto 0);
                Sel : in bit_vector (1 downto 0);
-- Output ports
Y : out bit
);
end entity;
 
-- Implementação com lógica pura
architecture v_logica_pura of mux4x1 is


architecture ifsc of divisor is
begin
begin
  Y <= (X(0) and (not Sel(1)) and (not Sel(0))) or
quociente <= dividendo / divisor;
      ...
resto <= dividendo rem divisor;
end architecture;
end architecture;
</syntaxhighlight>
</syntaxhighlight>


No entanto, o MUX4:1 também pode ser descrito utilizando a instrução '''WHEN-ELSE'''
{{fig|4.8|Código RTL do divisor com tipo integer com range| RTL_divisorv1.png| 300 px |}}
<syntaxhighlight lang=vhdl>
<optional_label>: <target> <=
<value> when <condition> else
<value> when <condition> else
...
<value> else
<value>;
</syntaxhighlight>


*Importante: O '''último ELSE''' sem condição para cobrir todos os demais valores para evitar a criação de LATCHES.
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.  
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]'''
{{fig|4.8|Código RTL do multiplicador por 4| RTL_multiplicador4.png| 300 px |}}


No caso do MUX4:1 ele poderia ser descrito como
{{fig|4.9|Código RTL do divisor por 2| RTL_divisor2.png| 300 px |}}
<syntaxhighlight lang=vhdl>
 
-- Implementação com WHEN ELSE
'''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.
architecture v_WHEN_ELSE of mux4x1 is
 
begin
{{fig|4.10|Código RTL do multiplicador por 10| RTL_multiplicador10.png| 300 px |}}
Y <= X(0) when Sel = "00" else
 
      X(1) when Sel = "01" else
O tipo INTEGER não é muito adequado para realizar as operações aritméticas por três motivos:  
      X(2) when Sel = "10" else
# Com INTEGER as operações só podem ser feita com no máximo 32 bits.
      X(3);
# Se não for dado um RANGE, as operações serão feitas com 32 bits, gerando hardware desnecessário
end architecture;
# Alguns simuladores (como o ModelSim) ao incrementarem um INTEGER além do valor máximo interrompem a simulação por overflow.
</syntaxhighlight>
{{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)


Outra forma de descrever o MUX4:1 seria utilizando a instrução '''WITH-SELECT'''
# 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


<syntaxhighlight lang=vhdl>
#Adiciona sinais ao waveform e mostra o valor em UNSIGNED
<optional_label>: with <expression> select
add wave -position end -radix unsigned sim:/$arq_vhd/a
<target> <=
add wave -position end -radix unsigned sim:/$arq_vhd/b
<value> when <choices>,
add wave -position end -radix unsigned sim:/$arq_vhd/s
<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.
# Força valores em b e varia a de 0 a 15


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


* 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>
# Ajustes visuais
-- Implementação com WITH SELECT
configure wave -timelineunits ns
architecture v_WITH_SELECT of mux4x1 is
wave zoom full
</syntaxhighlight>


begin
{{collapse bottom}}
  with Sel select
{{fig|4.11|Simulação com parada devido a erro de overflow no ModelSim | OverflowModelSim_somador_int.png| 800 px |}}
Y <= X(0) when "00",   -- note o uso da ,
Note que nessa simulação, ao atingir a soma 9 + 7 = 16, ocorre o overflow e o simulador indica o '''Fatal error''' e para.
      X(1) when "01",
  ** Fatal: (vsim-3421) Value '''16 is out of range 0 to 15.'''
      X(2) when "10",
 
      X(3) when others-- note o uso de others, para todos os demais valores. 
{{fig|4.12|Erro Fatal no ModelSim | OverflowModelSim.png| 800 px |}}
                        -- Não pode ser substituido por "11" mesmo que o signal seja bit_vector.
 
Veja como ficaria um somador usando o tipo UNSIGNED como portas de entrada e saída.
<syntaxhighlight lang=vhdl>
library ieee;
use ieee.numeric_std.all;
 
entity somador is
generic (N : natural := 4);
port (
a, b : in unsigned(N-1 downto 0);
s : out unsigned(4 downto 0)
);
end entity;
 
architecture ifsc of somador is
s <= a + b;
end architecture;
end architecture;
</syntaxhighlight>
</syntaxhighlight>


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


<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
-- Design Unit que associa a architecture com a entity
library ieee;
CONFIGURATION cfg_ifsc OF mux4x1 IS
use ieee.std_logic_1164.all;
FOR v_logica_pura END FOR;
use ieee.numeric_std.all;
-- FOR v_WHEN_ELSE END FOR;
-- FOR v_WITH_SELECT END FOR;
END CONFIGURATION;
</syntaxhighlight>


* 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. 
entity somador_slv is
* Note a diferença entre os RTL Viewer obtidos para cada architecture.
generic (N : natural := 4);
{{fig|2.1|Código RTL do mux4x1 v_logica_pura| RTL_mux4x1v1.png| 300 px |}}
port (
{{fig|2.2|Código RTL do mux4x1 v_WHEN_ELSE| RTL_mux4x1v2.png| 400 px |}}
a, b : in std_logic_vector(N-1 downto 0);
{{fig|2.3|Código RTL do mux4x1 v_WITH_SELECT| RTL_mux4x1v3.png| 200 px |}}
s : out std_logic(4 downto 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.
);
end entity;


;RESUMO:
architecture ifsc_v1 of somador_slv is
*[https://wiki.sj.ifsc.edu.br/images/5/5c/3-concorrente.pdf Slides Declarações Concorrentes]
begin
s <=  std_logic_vector(unsigned(a) + unsigned(b));
end architecture;


;PARA O PRÓXIMO ENCONTRO:
architecture ifsc_v2 of somador_slv is
*Realize a simulação das 3 arquiteturas do MUX4:1 no Modelsim
signal a_uns, b_uns : unsigned(N-1 downto 0);
*Crie um arquivo tb_mux4x1_v1.do que repita a simulação da arquitetura v1
signal s_uns : unsigned(N-1 downto 0);
*Crie um arquivo tb_mux4x1_v2.do que repita a simulação da arquitetura v2
begin
*Crie um arquivo tb_mux4x1_v3.do que repita a simulação da arquitetura v1
s <= std_logic_vector(s_uns)
*Inclua todos os arquivos .do no projeto do Quartus e salve o arquivo QAR
s_uns <= a_uns + b_uns;
*Ver essa página [[Simulação Funcional usando o ModelSim]]
a_uns <=  unsigned(a);
{{collapse bottom}}
a_uns <=  unsigned(b);
end architecture;
</syntaxhighlight>


===Unidade 2 - Dispositivos Lógicos Programáveis ===
{{fig|4.12|Simulação correta no ModelSim | SomadorModelSim.png| 800 px |}}
* 3 ENCONTROS
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.
{{collapse top | Unidade 2 - Dispositivos Lógicos Programáveis}}


;Encontro 5 (1 out):
Para utilizar corretamente os tipos UNSIGNED e SIGNED leia atentamente
*Introdução aos dispositivos lógicos programáveis:
*A biblioteca [[Numeric std.vhd]] define os tipos UNSIGNED e SIGNED.
:* Conceito, tipos de PLDs
:* SPLD:
::*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)]])
:* 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])


{{collapse top | expand=true| Exemplos de PLDs}}
<syntaxhighlight lang=vhdl>
{{fig|2.1|Exemplo de PAL| PedroniFig4_4a.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}
package NUMERIC_STD is
  type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
  type SIGNED is array (NATURAL range <>) of STD_LOGIC;
</syntaxhighlight>


{{fig|2.2|Exemplo de PLA| PedroniFig4_4b.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}
A biblioteca  [[Numeric std.vhd]] ainda define os operadores (abs, "+", "-", "*", "/", rem, mod, sll, slr, ror, rol), comparações ("=", '/=', ">", ">=", "<", "<=") e operadores lógicos (not, and, nand, or, nor, xor, xnor)  para os tipos SIGNED e UNSIGNED. Além disso também define algumas funções muito utilizadas como:


{{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}}
<syntaxhighlight lang=vhdl>
  --============================================================================
  --   RESIZE Functions
  --============================================================================
  function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
  function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;


{{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}}
  --============================================================================
  -- Conversion Functions
  --============================================================================
  function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
  function TO_INTEGER (ARG: SIGNED) return INTEGER;
  function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
  function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
</syntaxhighlight>
: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>


{{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}}
[[Arquivo:SumaryOfNumeric_std.gif]]


{{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}}
[[Arquivo:Numeric_stdConvertions.gif]]


{{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 }}
FONTE: http://www.doulos.com/knowhow/vhdl_designers_guide/numeric_std/


{{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}}
<center>
{{collapse bottom}}
{{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>


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


;PARA O PRÓXIMO ENCONTRO:
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).
*[https://www.intel.com/content/www/us/en/programmable/customertraining/webex/PLDBasics_History/presentation_html5.html History of Programmable Logic] Intel
*[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]
*[https://www.youtube.com/watch?v=ecyyZ6zTLic Microsoft's Bing* Intelligent Search with Intel® FPGAs]
*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.


;Encontro 6 (3 out):
{{collapse top | Mux2x1}}
* Arquitetura de FPGAs (Xilinx e Altera): CLB, LAB, LUT, Flip_flop D, RAM, DSP, Clock, PLL, DLL, I/O
A tabela verdade que descreve um MUX2:1 é mostrada abaixo:
:FONTE: [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA
<center>
 
{| class="wikitable" style="text-align:center;"
{{collapse top | expand=true |Exemplos de FPGA}}
|- style="font-weight:bold;"
 
! X1
{{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}}
! X0
 
! Sel
{{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}}
! style="background-color:#c0c0c0;" | Y
 
|-
{{fig|2.11|Arquitetura interna de uma LUT | LUT_FPGAs.png| 800 px | [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA}}
| 0
 
| 0
{{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
 
| style="background-color:#c0c0c0;" | 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}}
|-
 
| 0
{{fig|2.14|Leiaute de um FPGA Xilinx genérico | Leiaute2_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }}
| 0
 
| 1
{{fig|2.15|Roteamento de sinal em um FPGA | Roteamento_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }}
| style="background-color:#c0c0c0;" | 0
 
|-
{{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
 
| 0
: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]
| style="background-color:#c0c0c0;" | 1
 
|-
* [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
| 0
 
| 1
;PARA O PRÓXIMO ENCONTRO:
| 1
* Leia a assista a alguns dos vídeos sobre a historia e processo de produção dos chips.
| style="background-color:#c0c0c0;" | 0
:*[https://www.semiwiki.com/forum/content/1535-brief-history-fabless-semiconductor-industry.html A Brief History of the Fabless Semiconductor Industry]
|-
:*[http://www.semiwiki.com/forum/content/1539-brief-history-tsmc.html Taiwan Semiconductor Manufacturing Corporation (TSMC)], [http://www.globalfoundries.com/ GLOBALFOUNDRIES]
| 1
:*[https://www.linkedin.com/pulse/free-copy-fabless-transformation-semiconductor-industry-daniel-nenni-1 Fabless: The Transformation of the Semiconductor Industry, 2014] - Download free
| 0
:*[https://www.youtube.com/watch?v=W3rfVpkNquA Produção do FinFET], [https://www.youtube.com/watch?v=d9SWNLZvA8g]
| 0
:*[https://en.wikipedia.org/wiki/3_nm_process 3 nm process], [https://en.wikipedia.org/wiki/Multigate_device multi-gate MOSFET]
| style="background-color:#c0c0c0;" | 0
:*[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]
| 1
:*[https://www.youtube.com/watch?v=GU87SH5e0eI A dependência do mundo com a TMSC]
| 0
| 1
| style="background-color:#c0c0c0;" | 1
|-
| 1
| 1
| 0
| style="background-color:#c0c0c0;" | 1
|-
| 1
| 1
| 1
| style="background-color:#c0c0c0;" | 1
|}
</center>
 
O MUX2:1 também pode ser representado de forma resumida por:
<center>
{| class="wikitable" style="text-align:center;"
|- style="font-weight:bold;"
! X1
! 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:


;Encontro 7 (8 out):
* 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|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}}
<math>  Y =  \overline{Sel} . X0 + Sel . X1 </math>


* [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
Onde Y é a saída; Sel é o sinal de seleção; X0 e X1 são as entradas.
;PARA O PRÓXIMO ENCONTRO:
{{collapse bottom}}
:* Ver preços de DLPs em
::*[https://www.arrow.com/ ARROW]
::*[https://www.digikey.com/ Digikey]
::*[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


{{collapse bottom}}
{{collapse top | expand=false |Mux4x1}}
O MUX4:1 pode ser representado de forma resumida pela tabela verdade:


===Unidade 3 - Circuitos sequenciais (Implementação com HDL) ===
<center>
* 8 ENCONTROS
{| class="wikitable" style="text-align:center;"
{{collapse top | expand=true | Unidade 3 - Circuitos sequenciais (Implementação com HDL)}}
|- style="font-weight:bold;"
;Encontro 8 (10 out):
! colspan="4" | Entradas
*Flip-Flop e circuitos sequenciais.
! colspan="2" | Seleção
:*Diferenças entre código concorrente e sequencial <=> circuitos combinacional e sequencial
! Saída
:*Diferenças entre os objetos SIGNAL e VARIABLE
|- style="font-weight:bold;"
:*Tipos de elementos de memória: Latch x Flip-flop
| X3
::* Latch D
| X2
::* Flip-flop tipo D com reset assíncrono e com reset (clear) síncrono
| X1
:*Seção de código sequencial '''PROCESS''': lista de sensibilidade
| X0
<syntaxhighlight lang=vhdl>
| Sel1
[rótulo:] PROCESS [(lista_de_sensibilidade)] [IS]
| Sel0
            [parte_declarativa]
| style="background-color:#c0c0c0;" | Y
        BEGIN
|-
            afirmação_sequencial;
| -
            afirmação_sequencial;
| -
            ...
| -
        END PROCESS [rótulo];
| X0
</syntaxhighlight>
| 0
:*Instrução '''IF'''
| 0
<syntaxhighlight lang=vhdl>
| style="background-color:#c0c0c0;" | X0
[rótulo:] IF condição THEN
|-
            afirmação_sequencial;
| -
            afirmação_sequencial;
| -
            ...
| X1
        ELSIF condição THEN
| -
            afirmação_sequencial;
| 0
            afirmação_sequencial;
| 1
            ...
| style="background-color:#c0c0c0;" | X1
        ELSE
|-
            afirmação_sequencial;
| -
            afirmação_sequencial;
| X2
            ...
| -
        END IF [rótulo];
| -
| 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>
{{collapse bottom}}
 
Dada a função booleana do MUX4:1 é simples para descreve-lo em VHDL utilizando apenas operadores lógicos.


</syntaxhighlight>
:*Exemplos:
::* DFFs com Reset Assincrono e Reset Sincrono, com Enable, com Preset  (Variação Ex 6.1).
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
--Flip Flop tipo D com reset assincrono, sensivel a borda de subida.
entity mux4x1 is
process (clock,reset)
port
(
-- Input ports
X: in  bit_vector (3 downto 0);
                Sel : in bit_vector (1 downto 0);
-- Output ports
Y : out bit
);
end entity;
 
-- Implementação com lógica pura
architecture v_logica_pura of mux4x1 is
 
begin
begin
  if (reset = '1') then
Y <= (X(0) and (not Sel(1)) and (not Sel(0))) or
      q <= '0';
       ...
-- elsif (clock'event and clock = '1') then or
end architecture;
  elsif (rising_edge(clock)) then
       q <= d;
  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 | }}
 
No entanto, o MUX4:1 também pode ser descrito utilizando a instrução '''WHEN-ELSE'''
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
--Flip Flop tipo D com preset assincrono e sinal de enable, sensivel a borda de descida.
<optional_label>: <target> <=  
process (clock, preset)
<value> when <condition> else
begin
<value> when <condition> else
  if (preset = '1') then
...
      q <= '1';
<value> else
  elsif (falling_edge(clock)) then
<value>;
      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 out):
*Importante: O '''último ELSE''' sem condição para cobrir todos os demais valores para evitar a criação de LATCHES.
::* Comparar com Latch (sem clk'event).
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]'''
 
No caso do MUX4:1 ele poderia ser descrito como: 
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
--Latch tipo D com reset assincrono.
-- Implementação com WHEN ELSE
process (enable, reset, d)
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 (enable='1')) then
      X(2) when Sel = "10" else
      q <= d;
       X(3);
  end if;
end architecture;
end process;
</syntaxhighlight>
 
Outra forma de descrever o MUX4:1 seria utilizando a instrução '''WITH-SELECT'''
 
<syntaxhighlight lang=vhdl>
<optional_label>: with <expression> select
<target> <=  
<value> when <choices>,
<value> when <choices>,
...
<value> when others;
</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 | }}
*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.
 
Error (10313): VHDL Case Statement error ...: Case Statement choices must cover all possible values of expression


:* Ver pag. 151 a 156 de <ref name="PEDRONI2010b"/>
* 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'''.
:* 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]]


<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
-- Flip Flop tipo D com reset síncrono sensível a borda de subida.
-- Implementação com WITH SELECT
-- Modifique a descrição para que o reset_ass seja assíncrono e reset_sinc seja síncrono.
architecture v_WITH_SELECT of mux4x1 is
-- Note que a função rising_edge(clock) é equivalente a (clock'event and clock'last_value = '0' and clock = '1'))


process (clock, reset)
begin
begin
  if (reset = '1') then
with Sel select
      q <= '0';
Y <= X(0) when "00",    -- note o uso da ,
  elsif (clock'event and clock'last_value = '0' and clock = '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.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.  
* 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.
{{fig|5.6|RTL do Registrador (de 4 bits) com reset assíncrono| REG_RST.png| 400 px | }}
* Caso não se use a instrução CONFIGURATION, a última ARCHITECTURE será associada a ENTITY.
{{fig|5.7|Techonogy Map do Registrador (de 4 bits) com reset assíncrono| TM_REG_RST.png| 400 px | }}
* Apesar de apenas uma das ARCHITECTUREs ser associada, todas elas devem estar sintaticamente corretas, pois passarão pelo processo de ANÁLISE E SINTESE.
* Faça a simulação funcional do DFFs e do Latch
<syntaxhighlight lang=vhdl>
CONFIGURATION <configuration_name> OF <entity_name> IS
FOR <architecture_name> END FOR;
END CONFIGURATION;
</syntaxhighlight>


;Encontro 10 (17 out):
<syntaxhighlight lang=vhdl>
*Revisão de alguns tópicos tratados pelo prof. Roberto de Matos.
-- Design Unit que associa a architecture com a entity
CONFIGURATION cfg_ifsc OF mux4x1 IS
FOR v_logica_pura END FOR;
-- FOR v_WHEN_ELSE END FOR;
-- FOR v_WITH_SELECT END FOR;
END CONFIGURATION;
</syntaxhighlight>


;Encontro 11 (22 out):
* 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. 
*Simulação de contadores vistos nas aulas anteriores com o prof. Roberto de Matos.
* 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 |}}
;Encontro 12 e 13 (24 e 29 out.):
{{fig|2.2|Código RTL do mux4x1 v_WHEN_ELSE| RTL_mux4x1v2.png| 400 px |}}
*[https://drive.google.com/file/d/1O7zeVBDCJ_qKp6QTugiO0ax7N3nzGVjP/view?usp=drive_link Projeto de Circuitos Sequenciais: Princípios] Slides do prof. Roberto de Matos
{{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 14 (31 out.):
;RESUMO:
*Temporizações de um Flip-Flop.
*[https://wiki.sj.ifsc.edu.br/images/5/5c/3-concorrente.pdf Slides Declarações Concorrentes]
:*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 | RTL Hardware Desing, P. Chu }}
'''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.


Exemplos de contadores com projeto Sincrono.
;PARA O PRÓXIMO ENCONTRO:
*Contador de sequencia arbitraria (implementado com when else)
*Realize a simulação das 3 arquiteturas do MUX4:1 no Modelsim
*Contador de livre com indicação de valor máximo. (implementado com incrementador)
*Crie um arquivo tb_mux4x1_v1.do que repita a simulação da arquitetura v1
*Contador com opções de clear sincrono, load, e parada
*Crie um arquivo tb_mux4x1_v2.do que repita a simulação da arquitetura v2
*Contador de modulo 10.
*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}}


*Violação do tempo de Setup do FF e frequência máxima do circuito (Fmax).
===Unidade 2 - Dispositivos Lógicos Programáveis ===
{{fig|5.23|Modelo de Circuito Sequencial | SequencialCktModel.png | 800 px | RTL Hardware Desing, P. Chu }}


{{fig|5.24|Tempo de Setup e Fmax | SetupxFmax.png | 1000 px | RTL Hardware Desing, P. Chu }}
* 5 ENCONTROS
 
{{collapse top | expand=true | Unidade 2 - Dispositivos Lógicos Programáveis}}
{{fig|5.25|Equações do Tempo de Setup e Fmax (1/Tc(min)) | EquationSetupxFmax.png | 600 px | RTL Hardware Desing, P. Chu }}
<!--
 
;Encontro 2 (20 mar.):
{{fig|5.26|Equações do Tempo de Hold | EquationHold.png | 600 px | RTL Hardware Desing, P. Chu }}
 
{{fig|5.27|Atraso da saída | EquationOutputDelay.png | 600 px | RTL Hardware Desing, P. Chu }}


Exemplos de outros contadores com projeto síncrono.
*[https://drive.google.com/file/d/1VNUqU3nBkNWv3w-yT3HT18eY878JcgXz/view?usp=drive_link Introdução a linguagem de descrição de hardware (DHL)]
*Contador de modulo m (onde m é uma entrada).
:- Versão two_seg_clear_arch (12 EL, Fmax = 542,89 MHz para Slow 1,2V 125C Model)
:- Versão two_seg_effi_arch  (8 EL, Fmax = 444,64 MHz para Slow 1,2V 125C Model)
: O contador realiza '''m''' contagens, e precisa log2(m) registradores (flip-flops)


;Encontro 15 (5 nov.):
*ver [[Restringir a frequencia máxima de clock no Quartus]]
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
-- Instrução concorrente FOR GENERATE.
-- Exemplo: Declaração do circuito combinacional
-- Note que neste caso o '''label''' é obrigatório
-- Y = A'.B + A.B'
 
-- Autor:    prof. Marcos Moecke
label: FOR identificador IN faixa GENERATE
-- Data:     20/03/2025
  [Parte_Declarativa
-- Filename:  REV1.vhd
BEGIN]
-- A declaracao abaixo nao e necessaria pois o pacote standart da biblioteca std e autodeclarada (por default)
  Instruções_concorrentes
library std;
  ...
use std.standard.all;
END GENERATE [label];
</syntaxhighlight>


*Implementar um registrador de deslocamento de N bits.
--
<syntaxhighlight lang=vhdl>
entity REV1 is
entity shift_reg is
    port (a, B: in bit; y: out bit);
generic ( N : natural := 4);
port (
clock, reset : in  std_LOGIC ;
d_in: in std_LOGIC;
q_out : out std_LOGIC);
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;


*Implementar um registrador com N FF_D usando a instrução '''FOR GENERATE'''.
-- Implementacao com funcoes logica por etapas
</syntaxhighlight>
architecture ifsc_v2 of rev1 is
{{fig|5.8|Technology Map de Shift Register| shift_reg_TM.png| 800 px | }}
signal nota, notb : bit;    -- sinais internos podem ser declarados em uma unica linha se forem do mesmo tipo
{{fig|5.9|Simulação de Shift Register| shift_reg_SIM.png| 800 px | }}
signal and_1 : bit;          -- o nome dos sinais nao pode usar palavras reservadas do VHDL como and.
signal and_2 : bit;          -- usar uma linha para cada sinal pode ser uma boa pratica de documentacao
signal or_3 : bit;
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;
 
-- Implementacao com WHEN-ELSE
architecture ifsc_v3 of rev1 is
begin
 
end architecture;


*Implementar Uma porta or (and) ou xor de N entradas usando a instrução '''FOR GENERATE'''.
-- Implementacao com WITH-SELECT
architecture ifsc_v4 of rev1 is
begin


end architecture;


;Encontro 16 (7 nov.):
-- associacao da architetura a entidade.  
Instruções do tipo '''LOOP''': LOOP incondicional, '''FOR-LOOP''', '''WHILE-LOOP''', '''NEXT''', '''EXIT'''
-- 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;


*Instrução '''LOOP''' incondicional:
<syntaxhighlight lang=vhdl>
[rótulo:] LOOP
            afirmação_sequencial;
            afirmação_sequencial;
            ...
          END LOOP [rótulo];
</syntaxhighlight>
</syntaxhighlight>


*Instrução '''FOR-LOOP''':
;PARA O PRÓXIMO ENCONTRO:
<syntaxhighlight lang=vhdl>
* Alunos que fizeram ELD129002 : reveja [[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]]
[rótulo:] FOR identificador IN faixa LOOP
* Alunos que não fizeram ELD129002 : siga o procedimento [[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]]. 
            afirmação_sequencial;
* Se tiver dúvidas pergunte no chat da turma, que o professor ou algum colega pode ajudá-lo
            afirmação_sequencial;
 
            ...
* Implente e teste as várias versões de '''architecture''' da '''entity REV1''' .
          END LOOP [rótulo];
:1) diretamente com as funções lógicas
</syntaxhighlight>
:2) com funções lógicas por etapas
:3) com WHEN-ELSE
:4) com WITH-SELECT


*Instrução '''WHILE-LOOP''':
<syntaxhighlight lang=vhdl>
[rótulo:] WHILE condição LOOP            -- Executa as "afirmações enquanto a "condição" for verdadeira
            afirmação_sequencial;
            afirmação_sequencial;
            ...
          END LOOP [rótulo];
</syntaxhighlight>


*Instrução LOOP com '''EXIT''':
;Encontro 3 (25 mar.):
<syntaxhighlight lang=vhdl>
*Introdução aos dispositivos lógicos programáveis:
[rótulo:] [FOR identificador IN faixa] LOOP
:* Conceito, tipos de PLDs
            afirmação_sequencial;
:* SPLD:  
            EXIT [rótulo] [WHEN condição];    -- Se a "condição" é verdadeira, termina o "LOOP"
::*PAL (e.g. [https://wiki.sj.ifsc.edu.br/images/8/86/PAL16.pdf#page=5| PAL16 da Texas Instruments (1984)])
            afirmação_sequencial;
::*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)])
          END LOOP [rótulo];
:* 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])
</syntaxhighlight>
 
{{collapse top | expand=true| Exemplos de PLDs}}
{{fig|2.1|Exemplo de PAL| PedroniFig4_4a.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}


*Instrução LOOP com '''NEXT''':
{{fig|2.2|Exemplo de PLA| PedroniFig4_4b.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}
<syntaxhighlight lang=vhdl>
[rótulo:] [FOR identificador IN faixa] LOOP
            afirmação_sequencial;
            NEXT [rótulo] [WHEN condição];    -- Se a "condição" é verdadeira, não executa as linhas até a linha "END LOOP"
                                              -- e incrementa o "identificador".
            afirmação_sequencial;
            ...
          END LOOP [rótulo];
</syntaxhighlight>


*Instrução '''CASE''' 
{{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}}
<syntaxhighlight lang=vhdl>
[rótulo opcional:] CASE expressão IS
                  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:
{{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}}
* 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.5| Princípio de construção de uma LUT| LUT_pedroni.png | 400 px | https://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}}
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.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}}


begin
{{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}}
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.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 }}
:*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 | }}


*Ver pag. 161 a 164 de <ref name="PEDRONI2010b"/>
{{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}}
{{collapse bottom}}


<!--
;PARA O PRÓXIMO ENCONTRO:
*[https://youtu.be/7qa1dsCpMMo Memória EEPROM e FLASH] , [https://youtu.be/yLyQRtybfhc EEPROMs Market Value Explained] - Microchip (ingles)
*[https://www.youtube.com/watch?v=BA12Z7gQ4P0 Using an EEPROM to replace combinational logic] -  
*[https://www.intel.com/content/www/us/en/programmable/customertraining/webex/PLDBasics_History/presentation_html5.html History of Programmable Logic] Intel
*[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]
*[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]
*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.


*Implementar um contador crescente 0-N (baseado no Ex.6.2), com N = 2^Mbits-1 (1 3 7 15)
;Encontro 4 (27 mar.):
:*Com overflow no valor máximo
* Arquitetura de FPGAs (Xilinx e Altera): CLB, LAB, LUT, Flip_flop D, RAM, DSP, Clock, PLL, DLL, I/O
<syntaxhighlight lang=vhdl>
:FONTE: [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA
entity conta_0_N is
generic (MAX : natural := 15);
port (clock, reset: in  std_logic; q : out integer range 0  to MAX);
end entity;


architecture ifsc_v1 of conta_0_N is
{{collapse top | expand=true |Exemplos de FPGA}}


begin
{{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}}
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;
</syntaxhighlight>
{{fig|5.10|RTL de contador crescente| Counter_0_M_RTL.png| 600 px | }}
*Implementar um contador crescente 0 até N, com N ≠ 2^Mbits (5, 10)
:*Com overflow no valor máximo
{{fig|5.11|RTL contador crescente 0 a 5| Counter_0_5_RTL.png| 600 px | }}
{{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)
{{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}}
:*Com underflow no valor mínimo
{{fig|5.13|Simulação do contador decrescente 5 a 0| Counter_5_0_SIM.png| 800 px | }}


:*Com parada no valor mínimo
{{fig|2.11|Arquitetura interna de uma LUT | LUT_FPGAs.png| 800 px | [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA}}
{{fig|5.14|Simulação do contador decrescente 5 a 0 com parada| Counter_5_0_SIM_stop.png| 800 px | }}


{{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/}}


;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).
{{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}}
:*'''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.


[[Restringir a frequencia máxima de clock no Quartus II]]
{{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 }}


;Encontro 12 (2 abr.):
{{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}}


;Encontro 13  (5 abr.)
: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]
* 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.
* [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


<syntaxhighlight lang=vhdl>
* [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
library ieee;
 
use ieee.std_logic_1164.all;
;PARA O PRÓXIMO ENCONTRO:
* Leia a assista a alguns dos vídeos sobre a historia e processo de produção dos chips.
:*[https://www.semiwiki.com/forum/content/1535-brief-history-fabless-semiconductor-industry.html A Brief History of the Fabless Semiconductor Industry]
:*[http://www.semiwiki.com/forum/content/1539-brief-history-tsmc.html Taiwan Semiconductor Manufacturing Corporation (TSMC)], [http://www.globalfoundries.com/ GLOBALFOUNDRIES]
:*[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]
:*[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]
:*[https://www.youtube.com/watch?v=kU2SsUUsftA What is SRAM?], [https://www.youtube.com/watch?v=Lozf9sceW_o What is DRAM?] - Microchip
 
;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}}


entity carry_ripple_adder is
{{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}}
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 1 a 4
begin
 
-- Uso de um codigo sequencial para geracao de um circuito combinacional
;PARA O PRÓXIMO ENCONTRO:
process (a, b, cin) is
:* Ver preços de DLPs em
variable c : std_logic;
::*[https://www.arrow.com/ ARROW]
begin
::*[https://www.digikey.com/ Digikey]
c := cin;
::*[https://mouser.com Mouser Electronics]
for i in 0 to N-1 loop
::*[https://www.newark.com/  Newark]
s(i) <= a(i) xor b(i) xor c;
:* Fabricantes de DLPs/FPGAs e familias de DLPs atuais.
c := (a(i) and b(i)) or (a(i) and c) or (b(i) and c);
::*[https://www.altera.com/products/fpga/overview.html ALTERA/INTEL] - Stratix, Arria, Cyclone, Max, Agilex
end loop;
::*[https://www.xilinx.com/products/silicon-devices/fpga.html Xilinx/AMD] - Virtex, Kintex, Artix, Zynq (SoC)
cout <= c;
::*[https://www.microchip.com/en-us/products/fpgas-and-plds/fpgas Microchip] - Igloo, PolarFire
end process;
::*[http://www.latticesemi.com/Products.aspx#_D5A173024E414501B36997F26E842A31 Lattice]  - ECP, iCE, Mach
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 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
-->
-->
;Encontro 17 (12 nov.):
{{collapse bottom}}
* 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).


===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>
[rótulo:] WAIT UNTIL <condition>;
[rótulo:] PROCESS [(lista_de_sensibilidade)] [IS]
[rótulo:] WAIT ON sensitivity_list;
            [parte_declarativa]
[rótulo:] WAIT FOR time_expression;
        BEGIN
            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];


:Recomenda-se utilizar a lista de sensibilidade do PROCESS e a instrução IF no lugar do WAIT.
</syntaxhighlight>
:Algumas instruções de '''WAIT''' serão utilizadas na criação de '''TestBench''' em VHDL para a simulação com o '''MODELSIM'''.
:*Exemplos:
 
::* DFFs com Reset Assincrono e Reset Sincrono, com Enable, com Preset  (Variação Ex 6.1).
* 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 18 (14 nov.):
 
*Instrução '''IF GENERATE'''
 
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
<generate_label>:
--Flip Flop tipo D com reset assincrono, sensivel a borda de subida.
if <condition> generate
process (clock,reset)
-- Concurrent Statement(s)
begin
end generate;
  if (reset = '1') then
      q <= '0';
-- elsif (clock'event and clock = '1') then or
  elsif (rising_edge(clock)) then
      q <= d;
  end if;
end process;
</syntaxhighlight>
</syntaxhighlight>
 
{{fig|3.1|RTL de Flip-flop D de borda de subida, com reset assíncrono| FF_D_RST.png| 400 px | }}
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.
 
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:
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
entity contador_up_down_if_generate is
--Flip Flop tipo D com preset assincrono e sinal de enable, sensivel a borda de descida.
generic
process (clock, preset)
(
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_if_generate is
begin
begin
L1: if UPDOWN = 0 generate
  if (preset = '1') then
process (clk, rst)
      q <= '1';
variable cnt : integer range MIN to MAX;
  elsif (falling_edge(clock)) then
begin
      if (enable = '1') then
if rst = '1' then
        q <= d;
cnt := MIN;
      end if;
elsif (rising_edge(clk)) then
  end if;
if cnt = MAX then
end process;
cnt := MIN;
</syntaxhighlight>
else
{{fig|3.2|RTL de Flip-flop D de borda de descida, com preset assíncrono e enable| FF_D_PRST.png| 400 px | }}
cnt := cnt + 1;
::* Comparar com Latch (sem clk'event).
end if;
<syntaxhighlight lang=vhdl>
end if;
--Latch tipo D com reset assincrono.
count_out <= cnt;
process (enable, reset, d)
end process;
begin
end generate;
  if (reset = '1') then
L2: if UPDOWN = 1 generate
      q <= '0';
process (clk, rst)
  elsif (enable='1')) then
variable cnt : integer range MIN to MAX;
      q <= d;
begin
  end if;
if rst = '1' then
end process;
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 generate;
end architecture;
</syntaxhighlight>
</syntaxhighlight>
{{fig|3.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]]


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.4|Comparação do ''Technology Map'' de um Latch_D (esquerda) com FF_D (direita)| FF_D_LATCH_D.png| 800 px | }}
{{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 |}}
:* 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]]


*Uso de duas architecture para obter a mesma opção do '''IF GENERATE'''
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
entity contador_up_down_two_arch is
-- Flip Flop tipo D com reset síncrono sensível a borda de subida.
generic
-- Modifique a descrição para que o reset_ass seja assíncrono e reset_sinc seja síncrono.
(
-- Note que a função rising_edge(clock) é equivalente a (clock'event and clock'last_value = '0' and clock = '1'))
MIN : natural := 3;
 
MAX : natural := 21
process (clock, reset)
);
begin
port
  if (reset = '1') then
(
      q <= '0';
clk, rst   : in std_logic;
   elsif (clock'event and clock'last_value = '0' and clock = '1')) then
count_out  : out integer range MIN to MAX
      q <= d;
);
  end if;
end entity;
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]]
 
;Encontro 7 (8 abr.):


architecture arch_up of contador_up_down_two_arch is
*Exercício:  Implemente um registrador com N FF_D no lugar de um único FF_D.
begin
{{fig|3.6|RTL do Registrador (de 4 bits) com reset assíncrono| REG_RST.png| 400 px | }}
process (clk, rst)
{{fig|3.7|Techonogy Map do Registrador (de 4 bits) com reset assíncrono| TM_REG_RST.png| 400 px | }}
variable cnt : integer range MIN to MAX;
* Faça a simulação funcional do DFFs e do Latch
begin
 
if rst = '1' then
;Para o próximo encontro:
cnt := MIN;
*Use o script do arquivo de simulação tb_FFD_v_ruim.do para repetir a simulação feita em aula.
elsif (rising_edge(clk)) then
*Melhore o script eliminando comentários desnecessários.
if cnt = MAX then
*Deixe no inicio do script os comandos (alguns estarão comentados)
cnt := MIN;
vlib rtl_work
else
:Função: Criar uma biblioteca de trabalho chamada rtl_work.
cnt := cnt + 1;
vmap work rtl_work
end if;
:Função: Faz o mapeamento da biblioteca padrão work para a biblioteca rtl_work criada anteriormente.
end if;
vcom -93 -work work {../../FFD_N.vhd}
count_out <= cnt;
: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.
end process;
vsim work.ffd_n(ifsc_v1)
end architecture;
: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.


architecture arch_down of contador_up_down_two_arch is
*Para cada estímulo (entrada) faça com que haja apenas uma linha de comando '''force''' usando o padrão abaixo:
begin
force -freeze sim:/ffd_n/<nome do estimulo> valor1 tempo1, valor2 tempo2, valor3 tempo3
process (clk, rst)
*Para a entrada '''clock''' use:
variable cnt : integer range MIN to MAX;
force -freeze sim:/ffd_n/clock v1 t1, v2 t2 -r Tclk
begin
:onde:
if rst = '1' then
::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.
cnt := MAX;
::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)
elsif (rising_edge(clk)) then
::o tempo Tclk é o período em que o sinal deve ser repetido.
if cnt = MIN then
:Exemplo de um sinal de período de 100ps => fclk = 10GHz;
cnt := MAX;
force -freeze sim:/ffd_n/clock 1 0, 0 50 -r 100
else
*Conclua a simulação com uma linha de '''run''' que seja suficiente para variar todos os estímulos e obter os resultados:
cnt := cnt - 1;
run XXX ps ou 
end if;
run XXX ns|us|ms|sec|min|hr
end if;
*Para visualizar todo o período de tempo simulado inclua o seguinte comando no script
count_out <= cnt;
wave zoom full
end process;
end architecture;


configuration ifsc_cfg of contador_up_down_2arch is
*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
-- for arch_up end for;
<pre>
for arch_down end for;
=========== Files Selected: ===========
end configuration;
/home/moecke/ELD2/2025.1/AULA7/FFD_N.qpf
</syntaxhighlight>
/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>


*Uso de uma porta de entrada UPDOWN fixada em '0' ou '1' para obter a mesma opção do '''IF GENERATE'''
;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> }}


<syntaxhighlight lang=vhdl>
*'''External Input''': Entradas externas fornecem os sinais que afetam a transição entre estados.
entity contador_up_down_pin is
*'''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.
generic
*'''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).
(
* '''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):
MIN : natural := 3;
:*'''Moore''': Saída depende apenas do estado.
MAX : natural := 21
:*'''Mealy''': Saída depende do estado e das entradas.
);
 
port
:Funcionamento - Fluxo de dados:
(
*O sinal de clock (clk) sincroniza todas as mudanças de estado.
clk, rst   : in std_logic;
*O registrador atualiza seu valor na borda do clock, armazenando o ''state_next'' calculado anteriormente.
UPDOWN : natural := 1; -- 0 => up; 1 => down
*A lógica combinacional (tanto de próximo estado quanto de saída) opera continuamente, processando entradas e o estado atual.
count_out  : out integer range MIN to MAX
*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.
end entity;
 
;Encontro 9 (15 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
*Contador binário livre com pulso de máximo
:*Código com 2 segmentos: 1) parte sequencial (apena atualiza o r_reg) 2) parte combinatória (cálcula o r_next)
:*Código com 1 segmento: todo o código fica em um único process.
*Contador decimal (mod-10)
*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.
;DOIS segmentos vs. UM segmento:
*Código de dois segmentos
:*Separa o segmento de memória do resto do código;
:*Pode ser um pouco complicado (lógica separada);
:*Tem um mapeamento claro para o componente de hardware.
*Código de um segmento
:*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.


architecture ifsc_v1 of contador_up_down_pin is
<syntaxhighlight lang=vhdl>
signal cnt_down, cnt_up  : integer range MIN to MAX;
architecture extra_ff_max_pulse of binary_counter4_pulse is
  signal r_reg: unsigned(3 downto 0);
begin
begin
process (clk, rst)
  process(clk,reset)
variable cnt : integer range MIN to MAX;
  begin
begin
      if (reset='1') then
if rst = '1' then
        r_reg <= (others=>'0');
cnt := MIN;
      elsif rising_edge(clk) then
elsif (rising_edge(clk)) then
        r_reg <= r_reg + 1;
if cnt = MAX then
        if r_reg="1111" then
cnt := MIN;
            max_pulse <= '1';
else
        else
cnt := cnt + 1;
            max_pulse <= '0';
end if;
        end if;
end if;
      end if;
cnt_up <= cnt;
  end process;
end process;
  q <= std_logic_vector(r_reg);
 
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;
end architecture;
</syntaxhighlight>
</syntaxhighlight>
*Uso de componentes e instanciação de componentes.
{{fig|5.22|Diagrama RTL contador com max_pulse output | max_pulse_RTL.png | 600 px | }}
<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 adaptadasAs 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 | Resposta do ChatGPT}}
{{fig|5.22|Diagrama RTL contador com extra flip-flop in max_pulse output | FF_max_pulse_RTL.png | 600 px |  }}


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:
{{fig|5.23|Simulação do extra flip-flop in max_pulse output - errado| FF_max_pulse_SIM.png | 600 px |  }}


; Declaração do componente:
{{fig|5.24|Simulação do max_pulse output - correto | max_pulse_SIM.png | 600 px |  }}
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.


Exemplo de declaração do componente:
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.


<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
component MeuComponente
architecture one_seg_arch_signal of mod10_counter is
    generic (
  constant TEN: integer := 10;
        WIDTH : natural := 4
  signal r_reg: unsigned(3 downto 0);
    )
begin
    port (
  -- register
        clk   : in  std_logic;
  process(clk,reset)
        reset : in  std_logic;
  begin
        data  : in  std_logic_vector(7 downto 0);
      if (reset='1') then
        valid : out std_logic
        r_reg <= (others => '0');
    );
      elsif rising_edge(clk) then
end component;
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>
</syntaxhighlight>


;Instanciação do componente:
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.
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.
<syntaxhighlight lang=vhdl>
 
architecture one_seg_arch_variable of mod10_counter is
Exemplo:
  constant TEN: integer := 10;
begin
  -- register
  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_reg. Neste 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.


;Para o próximo encontro:
*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'''.
*Exemplo do que pode ter no state register:
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
Instancia2: MeuComponente
-- state register
    generic map (
  process(clock,reset)
         8
  begin
    )
      if (reset='1') then
    port map (
         centena_reg <= (others=>'0');
        clk_signal,
        dezena_reg <= (others=>'0');
        reset_signal,
        unidade_reg <= (others=>'0');
        input_data,
      elsif rising_edge(clock) then
        output_valid
        centena_reg <= centena_next;
    );
        dezena_reg <= dezena_next;
        unidade_reg <= unidade_next;
      end if;
  end process;
</syntaxhighlight>
</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.
 
;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
 
*Variações do contador BCD
:*Em 2 segmentos com WHEN ELSE
:*Em 2 segmentos com IFs aninhados
*Registrador de Deslocamento
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>
<syntaxhighlight lang=vhdl>
Instancia1: MeuComponente
r_next(3) <= d;
    generic map (
r_next(2) <= r_reg(3);
        WIDTH => 8
r_next(1) <= r_reg(2);
    )
r_next(0) <= r_reg(1);
    port map (
q <= r_reg(0);
        clk  => clk_signal,
        reset => reset_signal,
        data  => input_data,
        valid => output_valid
    );
</syntaxhighlight>
</syntaxhighlight>
No exemplo acima
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.
*'''Instancia1''' é o rótulo da instância.
:*Atribuições bit a bit com '''for generate''':
*'''clk, reset, data,''' e '''valid''' são os nomes das portas do componente.
<syntaxhighlight lang=vhdl>
*'''clk_signal, reset_signal, input_data''', e '''output_valid''' são os sinais do módulo que está utilizando o componente.
r_next(3) <= d;
l1: for i in 2 downto 0 generate
r_next(i) <= r_reg(i + 1);
end generate;
q <= r_reg(0);
</syntaxhighlight>
Esta versão combina clareza com generalização. Assim como a primeira, é facilmente adaptável para registradores de qualquer tamanho.
 
'''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.


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.
;Para o próximo encontro:
*'''DESAFIO''': Desenvolver um contador genérico capaz de contar em BCD com qualquer número de dígitos.


;Arquivo da Entidade (Componente):
;Encontro 11 (22 abr.):
Um arquivo que define uma entidade (componente) deve conter:
:*Para replicar hardware várias vezes, utilize estruturas como: '''for generate''' ou  '''for loop'''
*A declaração da entidade, que define as entradas e saídas do módulo.
*Instrução Concorrente '''FOR-GENERATE''':
*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>
<syntaxhighlight lang=vhdl>
-- Arquivo: MeuComponente.vhd
-- Note que neste caso o '''label''' é obrigatório
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


-- Declaração da entidade
label: FOR identificador IN faixa GENERATE
entity MeuComponente is
  [Parte_Declarativa
    port (
  BEGIN]
        clk  : in  std_logic;
    afirmação_concorrente;
        reset : in  std_logic;
    afirmação_concorrente;
        data  : in  std_logic_vector(7 downto 0);
    ...
        valid : out std_logic
  END GENERATE [label];
    );
</syntaxhighlight>
end MeuComponente;


-- Declaração da arquitetura
*Instrução Sequencial '''FOR-LOOP''':
architecture Behavioral of MeuComponente is
<syntaxhighlight lang=vhdl>
begin
[rótulo:] FOR identificador IN faixa LOOP
    -- Implementação da lógica do componente
            afirmação_sequencial;
    process(clk, reset)
            afirmação_sequencial;
    begin
            ...
        if reset = '1' then
          END LOOP [rótulo];
            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>
</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:
*Implementar um registrador com N FF_D usando a instrução '''FOR GENERATE'''.
<syntaxhighlight lang=vhdl>
 
-- Arquivo: TopLevel.vhd
{{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 | }}


library IEEE;
*Implementar uma porta or (and) ou xor de N entradas usando a instrução '''FOR GENERATE'''.
use IEEE.STD_LOGIC_1164.ALL;


-- Declaração da entidade do Top Level
Novas dicas para representar N dígitos BCD, cada um com 4 bits, será necessário criar um novo tipo de dado:
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
<syntaxhighlight lang=vhdl>
architecture Structural of TopLevel is
  type bcd_digits is array (natural range <>) of unsigned(3 downto 0);
    -- Sinais internos para conexão
  signal bcd  : bcd_digits(0 to N-1);  
    signal clk_signal  : std_logic;
</syntaxhighlight>
    signal reset_signal : std_logic;
:*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:
    signal input_data  : std_logic_vector(7 downto 0);
<syntaxhighlight lang=vhdl>
    signal output_valid : std_logic;
library work;
use work.nome_do_pacote.all;
</syntaxhighlight>


    -- Declaração do componente
;Para o próximo encontro:
    component MeuComponente
*'''DESAFIO''': Desenvolver um contador genérico capaz de contar em BCD com qualquer número de dígitos.
        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
;Encontro 12 (24 abr.):
    Instancia1: MeuComponente
*Temporizações de um Flip-Flop.
        port map (
:*atraso do clock para saída (Tcq)
            clk  => clk_signal,
:*tempo de setup (T_{setup}) e tempo de hold (T_{hold})
            reset => reset_signal,
{{fig|5.22|Temporizações de um Flip Flop | FF_timing.png | 600 px |  <ref name="CHU2006"/> }}
            data => input_data,
'''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.
            valid => output_valid
*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).
 
 
;Encontro 13 (29 abr.):
Instruções do tipo '''LOOP''': LOOP incondicional, '''FOR-LOOP''', '''WHILE-LOOP''', '''NEXT''', '''EXIT'''


    -- Conectando o sinal interno à saída global
*Instrução '''LOOP''' incondicional:
    valid <= output_valid;
<syntaxhighlight lang=vhdl>
end Structural;
[rótulo:] LOOP
            afirmação_sequencial;
            afirmação_sequencial;
            ...
          END LOOP [rótulo];
</syntaxhighlight>
</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:


*Instrução '''WHILE-LOOP''':
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
Instancia1: MeuComponente
[rótulo:] WHILE condição LOOP            -- Executa as "afirmações enquanto a "condição" for verdadeira
    port map (
            afirmação_sequencial;
        clk  => clk,
            afirmação_sequencial;
        reset => reset,
            ...
        data  => (others => '0'), -- Porta de entrada não utilizada
          END LOOP [rótulo];
        valid => valid_signal
    );
</syntaxhighlight>
</syntaxhighlight>


No exemplo acima, a entrada data foi conectada a (others => '0'), indicando que todos os bits do vetor serão definidos como 0.
*Instrução LOOP com '''EXIT''':
 
<syntaxhighlight lang=vhdl>
;Para uma Porta de Saída Não Utilizada:
[rótulo:] [FOR identificador IN faixa] LOOP
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'''.
            afirmação_sequencial;
 
            EXIT [rótulo] [WHEN condição];    -- Se a "condição" é verdadeira, termina o "LOOP"
Exemplo:
            afirmação_sequencial;
            ...
          END LOOP [rótulo];
</syntaxhighlight>


*Instrução LOOP com '''NEXT''':
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
Instancia3: MeuComponente
[rótulo:] [FOR identificador IN faixa] LOOP
    port map (
            afirmação_sequencial;
        clk  => clk,
            NEXT [rótulo] [WHEN condição];    -- Se a "condição" é verdadeira, não executa as linhas até a linha "END LOOP"
        reset => reset,
                                              -- e incrementa o "identificador".
        data  => data_signal,
            afirmação_sequencial;
        valid => open -- Porta de saída não utilizada
            ...
    );
          END LOOP [rótulo];
</syntaxhighlight>
</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 19 e 20 (19 e 21 nov.):
*Projetar um conversor de BCD para SSD - display de sete segmentos ('''bcd2ssd.vhd''').  O circuito 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 do componente '''bcd2ssd'''.
:1) Onde é usado a entrada do tipo anodo comum e catodo comum em diferentes instâncias para testar ambos os tipos de mostradores.
:2) 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.
O projeto top_level deve incluir uma entrada BCD de 4 bits e os sinais de controle para o tipo de mostrador (anodo comum ou catodo comum) e a ativação/desativação do zero.


*Instrução '''CASE''' 
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
entity top_level is
[rótulo opcional:] CASE expressão IS
port (
                  WHEN valor =>                            -- valor único
bcd_tl      : in std_logic_vector(3 downto 0);
                    afirmação_sequencial;                          
ACn_CC      : in std_logic; -- '1' para anodo comum, '0' para catodo comum
                    afirmação_sequencial;                          
Z_OPC        : in std_logic; -- '1' para mostrar zero, '0' para ocultar
                    ...
ssd1        : out std_logic_vector(6 downto 0);
                  WHEN valor1 | valor2 | ... | valorN  =>  -- lista de valores
ssd2        : out std_logic_vector(6 downto 0);
                    afirmação_sequencial;                          
ssd3        : out std_logic_vector(6 downto 0);
                    afirmação_sequencial;                          
ssd4        : out std_logic_vector(6 downto 0)
                    ...
);
                  WHEN valor1 TO valor2 =>                  -- faixa de valores
end entity;
                    afirmação_sequencial;                          
 
                    afirmação_sequencial;  
architecture ifsc of top_level is
                    ...
component bcd2ssd is
                  WHEN OTHERS  =>                         -- para evitar latches
port (
                    afirmação_sequencial;                          
bcd          : in std_logic_vector(3 downto 0);
                    afirmação_sequencial;  
ACn_CC      : in std_logic;
                    ...
Z_OPC        : in std_logic;
          END CASE;
ssd          : out std_logic_vector(6 downto 0)
);
end component;
begin
u1 : bcd2ssd
port map(bcd_tl => bcd, ACn_CC => '1', Z_OPC => '1', ssd => ssd1);
u2 : bcd2ssd
port map(bcd_tl => bcd, ACn_CC => '1', Z_OPC => '0', ssd => ssd2);
u3 : bcd2ssd
port map(bcd_tl => bcd, ACn_CC => '0', Z_OPC => '1', ssd => ssd3);
u4 : bcd2ssd
port map(bcd_tl => bcd, ACn_CC => '0', Z_OPC => '0', ssd => ssd4);
end architecture;
</syntaxhighlight>
</syntaxhighlight>


*Faça a simulação do componente bcd2ssd e também do top_level.
;Exemplos:
*Em seguida configure o circuito para ser implementado nos 4 mostradores (HEX0, HEX1, HEX2, HEX3).  Para entrada de dados utilize as chaves SW3 downto SW0 do kit DE2-115.
* 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>
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;


*Ver funcionamento do [[Display de 7 segmentos]]
architecture ____ of leading_zeros is


;Encontro 21 (26 nov.):
begin
 
process (data)
* 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''')
variable count : integer ____ 0 to N
:* Utilize esse circuito para obter um clock de 1 Hz a partir do sinal de 50MHz existente no kit DE2-115.
begin
:* Utilize um segundo circuito para obter um clock de 0,1 Hz
count := 0;
:* Teste o circuito no kit DE2-115.
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'''.
:*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 | }}


;Encontro 22 (28 nov.):
*Ver pag. 161 a 164 de <ref name="PEDRONI2010b"/>
*Contador Gray (só troca um bit por vez) [https://drive.google.com/file/d/1GTkw-JvBRljvfJJNOA_cGmZzWkKDhp8M/view?usp=drive_link Listagem 9.7 do livro do P. Chu]
:: ver [[Código Gray]]
*Contador em anel (desloca um padrão inicial) [https://drive.google.com/file/d/1KEswDlpNqbgROcsr4MMh4BCr2tmDB3-k/view?usp=drive_link Listagem 9.8 e 9.9 do livro do P. Chu]
*Contador Johnson (uso de um inversor na realimentação do contador em anel)
*Contador LFSR (Linear Feedback Shift Register) [https://drive.google.com/file/d/1wjypyztGMxiUxsPNwZ8j-PQkTMwoyFu3/view?usp=drive_link Listagem 9.10 e 9.11 do livro do P. Chu]


;Encontro 23 (3 dez.):
;Encontro 14 (6 mai.):
* Implementar um contador [https://en.wikipedia.org/wiki/Linear-feedback_shift_register LFSR] de n bits. 
*Implemente o contador de sequencia arbitraria (implementado com when else) (ver Listing 8.11 - Arbitrar-sequence counter).
* 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.
*Implemente o contador com opções de clear sincrono, load, e parada (ver Listing 8.13 - Featured binary counter).
*'''Circuito de PWM''' (''Pulse Width Modulation'' - Modulação por largura de pulso) [https://drive.google.com/file/d/1FLvKLrSAZs9HQkz-QxkB3rsDHyGryf1-/view?usp=drive_link Listagem 9.14 do livro do P. Chu].  
*Implemente o contador de modulo m (onde m é uma entrada) (ver Listing 8.15 e 8.16 - Programmable mod-m counter).
:*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.


:*Note que uma expressão booleana adicional, w="0000", é incluída para acomodar a condição especial.
;Encontro 15 (8 mai.):
* 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''')
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
   buf_next <= '1' when (r_reg<unsigned(w)) or (w="0000") else '0';
entity div_clk  is
   port(
    clk:      in std_logic;
    reset:    in std_logic;
clk_1ms:  out std_logic;
clk_10sec: out std_logic;
clk_1sec:  out std_logic
  );
end entity;
</syntaxhighlight>
</syntaxhighlight>
{{fig|5.X|RTL do circuito de PWM| PWM_RTL.png| 600 px | }}
:* 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.
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.
{{fig|5.X|Simulação do circuito de PWM| PWM_SIM.png| 1000 px | }}


;Encontro 24 e 25 (5 e 10 dez.)
;Para o próximo encontro:
*Implementação de um relógio HHMMSS usando os componentes desenvolvidos nas aulas anteriores.
*Completar o projeto do divisor de clock, acrescentando:
*[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]
:*Implemente uma segunda saída para um clock de 1kHz (1 ms) '''clk_1ms'''
*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.
:*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]
 
*Preparar o código dos seguintes circuitos:
:*Contador de segundos e minutos com clock derivado (ver Listing 9.5)
:*Contador de segundos e minutos síncrono (ver Listing 9.6)
 
;Encontro 16 (13 mai.):
*Fazer a compilação completa, simular e fazer o timing analysis dos seguintes circuitos:
:*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"/>}}


;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.)
;Encontro 17(15 mai.):
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.
*Contador binario sequencial
  b_next <= b_reg+1;


* Registradores como armazenamento temporário
*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"/>]
:: ver [[Código Gray]]
  b <= g_reg xor ('0' & b(WIDTH-1 downto 1));
  b1 <= b+1;
  g_next <= b1 xor ('0' & b1(WIDTH-1 downto 1));


{{collapse bottom}}
*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"/>]
  r_next <= r_reg(0) & r_reg(WIDTH-1 downto 1);


===Unidade 4 - Maquinas de Estado Finitas===
*Contador Johnson (uso de um inversor na realimentação do contador em anel)
  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.


{{collapse top | expand=true | Unidade 4 - Maquinas de Estado Finitas}}
;Encontro 18(20 mai.):
;Encontro 29  (28 jan.)
*'''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"/>].
* O que é uma FSM - Finite State Machine
:*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.
{{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"/>}}
:*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. 
* Modelo básico em VHDL de FSM
 
<syntaxhighlight lang=vhdl>
:*Note que uma expressão booleana adicional, w="0000", é incluída para acomodar a condição especial.
LIBRARY ieee;
<syntaxhighlight lang=vhdl>
USE ieee.std_logic_1164.ALL;
  buf_next <= '1' when (r_reg<unsigned(w)) or (w="0000") else '0';
----------------------------------------------------------
</syntaxhighlight>
ENTITY < entity_name > IS
{{fig|5.X|RTL do circuito de PWM| PWM_RTL.png| 600 px | }}
PORT (
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.
clk, rst : IN STD_LOGIC;
{{fig|5.X|Simulação do circuito de PWM| PWM_SIM.png| 1000 px | }}
entradas : IN < data_type > ;
 
saidas : OUT < data_type >);
*Implementar um contador decrescente N até 0, com N ≠ 2^Mbits (5, 10)
END entity;
:*Com underflow no valor mínimo
----------------------------------------------------------
{{fig|5.13|Simulação do contador decrescente 5 a 0| Counter_5_0_SIM.png| 800 px | }}
ARCHITECTURE < architecture_name > OF < entity_name > IS
 
TYPE state IS (A, B, C, ...);
*Implementar um contador decrescente com parada no valor mínimo
SIGNAL pr_state, nx_state : state;
{{fig|5.14|Simulação do contador decrescente 5 a 0 com parada| Counter_5_0_SIM_stop.png| 800 px | }}
-- ATTRIBUTE ENUM_ENCODING : STRING; --optional attribute
 
-- ATTRIBUTE ENUM_ENCODING OF state : TYPE IS "sequential";
*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).
-- ATTRIBUTE SYN_ENCODING OF state : TYPE IS "safe";
:*'''Versão 1:''' Com underflow no valor mínimo (MIN) e overflow no máximo (MAX).
BEGIN
:*'''Versão 2:''' Com parada no valor mínimo (MIN), se decrescente e também no máximo (MAX) se crescente.
------Logica Sequencial da FSM:------------
;Encontro 19 (22 mai.):
PROCESS (clk, rst)
*Instrução '''IF GENERATE'''
BEGIN
 
IF (rst = '1') THEN
<syntaxhighlight lang=vhdl>
pr_state <= A;
<generate_label>:
ELSIF rising_edge(clk) THEN
if <condition> generate
-- apenas na borda do "clk" ocorre a mudança de estado da FSM
-- Concurrent Statement(s)
pr_state <= nx_state;
end generate;
END IF;
</syntaxhighlight>
END PROCESS;
 
------Logica Combinacional da FSM:------------
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.
PROCESS (pr_state, entradas)
 
BEGIN
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 escrito em segmento único e usando variável:
------Valores default das saidas------------
<syntaxhighlight lang=vhdl>
                saidas <= < valor > ;
entity contador_up_down_if_generate is
CASE pr_state IS
generic
WHEN A =>
(
-- é necessário um  WHEN para definir as "saidas" durante cada estado
MIN    : natural := 3;
-- e analisar as "entradas" para definir o próximo estado
MAX    : natural := 21;
saidas <= < valor > ;  -- apenas se diferente do valor default
UPDOWN  : natural := 0          -- 0 => up; 1 => down
IF (entradas = < valor >) THEN
);
nx_state <= B;
port
...
(
ELSE
clk, rst  : in std_logic;
nx_state <= A;
cnt_out    : out integer range MIN to MAX  -- Aqui deveria ser usado std_logic_vector
END IF;
);
WHEN B =>
end entity;
saidas <= < valor > ; -- apenas se diferente do valor default
</syntaxhighlight>
-- 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 ...


 
<syntaxhighlight lang=vhdl>
END CASE;
architecture ifsc_v1 of contador_up_down_if_generate is
END PROCESS;
begin
------Seção de Saída (opcional):-------
L1: if UPDOWN = 0 generate
-- Essa seção visa garantir que a saida new_output esteja sincronizada com o clk. 
process (clk, rst)
-- Se isso não for importante, ela pode ser suprimida
variable cnt : integer range MIN to MAX;
PROCESS (clk, rst)
begin
BEGIN
if rst = '1' then
IF (rst = '1') THEN
cnt := MIN;
new_output <= < valor > ;
elsif (rising_edge(clk)) then
ELSIF rising_edge(clk) THEN --or falling_edge(clk)
if cnt = MAX then
new_output <= output;
cnt := MIN;
END IF;
else
END PROCESS;
cnt := cnt + 1;
END architecture;
end if;
</syntaxhighlight>
end if;
;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
cnt_out <= cnt;
<syntaxhighlight lang=vhdl>
end process;
WHEN others =>
end generate;
nx_state <= <initial_state>;
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>
</syntaxhighlight>


:* Usando o template acima descreva em VHDL a FSM indicada na Figura 11.1.
Agora analise o mesmo contador descrito em dois segmentos, parte sequencial e parte de logica de próximo estado:
:* 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 30  (30 jan.)
<syntaxhighlight lang=vhdl>
:* Máquina de vendas
architecture ifsc_v2 of contador_up_down_if_generate is
::*Use o template da FSM para modelar o sistema mostrado na figurar a seguir.
    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;


{{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"/> }}
    -- 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>


{{fig|7.3|FSM - Máquina de vendas (diagrama de estados com default |FSM_MVD_default.png|800 px|}}
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 |}}  


::*Simule a FSM com Modelsim utilizando um testbench em VHDL para gerar o teste mostrado na figura abaixo.
*Uso de duas architecture para obter a mesma opção do '''IF GENERATE'''
{{fig|7.4|FSM - Máquina de vendas (simulação)|FSM_tb40.png|800 px|}}
<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;


:* 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.
architecture arch_up of contador_up_down_two_arch is
 
begin
:: Ver pag. 281 a 282 de <ref name="PEDRONI2010b"/>
process (clk, rst)
:: '''Dica''':  para desenhar a FSM recomendo utilizar um software on-line para tal finalidade.  Por Ex.  [https://online.visual-paradigm.com/pt/ Visual Paradigm].
variable cnt : integer range MIN to MAX;
 
begin
;DESAFIO:
if rst = '1' then
*Implementar um controlador para máquina de Lavar Roupas baseado na FSM abaixo.
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;


{{fig|7.4|FSM da Máquina de Lavar Roupas |FSM_LavaRoupas.png|1200 px|}}
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;


;PARA A PRÓXIMA AULA:
configuration ifsc_cfg of contador_up_down_2arch is
* Implementação em VHDL da FSM de máquina de Lavar Roupas
-- for arch_up end for;
* Simulação em ModelSim da FSM de máquina de Lavar Roupas
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'''
;Encontro 31 (4 fev.)
* 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''). Exemplo da modelagem de um controlador de memória com modo de leitura '''BURST'''.
{{fig|4.4|Diagrama de estados de um controlador de memória|Mem_ctrl_SD.png|400 px|RTL Hardware Desing, P. Chu}}
 
{{fig|4.5|ASM de um controlador de memória|Mem_ctrl_ASM.png|400 px|RTL Hardware Desing, P. Chu}}
* 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>
<syntaxhighlight lang=vhdl>
library ieee;
entity contador_up_down_pin is
use ieee.std_logic_1164.all;
generic
entity mem_ctrl is
(
port (
MIN : natural := 3;
clk            : in std_logic;
MAX : natural := 21
reset          : in std_logic;
);
mem, rw, burst : in std_logic;
port
oe, we, we_me  : out std_logic
(
clk, rst   : in std_logic;
UPDOWN : natural := 1; -- 0 => up; 1 => down
count_out  : out integer range MIN to MAX
);
);
end entity;
end entity;
architecture two_seg_arch2 of mem_ctrl is
 
type mc_state_type is
architecture ifsc_v1 of contador_up_down_pin is
(idle, read1, read2, read3, read4, write1);
signal cnt_down, cnt_up  : integer range MIN to MAX;
signal state_reg, state_next : mc_state_type;
begin
begin
process (clk, reset)
process (clk, rst)
begin
variable cnt : integer range MIN to MAX;
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
begin
oe    <= '0';
if rst = '1' then
we    <= '0';
cnt := MIN;
we_me <= '0';
elsif (rising_edge(clk)) then
case state_reg is
if cnt = MAX then
when idle =>
cnt := MIN;
if mem = '1' then
if rw = '1' then
state_next <= read1;
else
state_next <= write1;
we_me      <= '1';
end if;
else
else
state_next <= idle;
cnt := cnt + 1;
end if;
end if;
when write1 =>
end if;
we        <= '1';
cnt_up <= cnt;
state_next <= idle;
end process;
when read1 =>
 
oe <= '1';
process (clk, rst)
if (burst = '1') then
variable cnt : integer range MIN to MAX;
state_next <= read2;
begin
if rst = '1' then
cnt := MAX;
elsif (rising_edge(clk)) then
if cnt = MIN then
cnt := MAX;
else
else
state_next <= idle;
cnt := cnt - 1;
end if;
end if;
when read2 =>
end if;
oe        <= '1';
cnt_down <= cnt;
state_next <= read3;
end process;
when read3 =>
count_out <= cnt_up when UPDOWN = 1 else cnt_down;
oe        <= '1';
state_next <= read4;
when read4 =>
oe        <= '1';
state_next <= idle;
end case;
end process;
end architecture;
end architecture;
</syntaxhighlight>
</syntaxhighlight>
Fonte: adaptado de RTL Hardware Desing, P. Chu.


{{fig|4.6|RTL do controlador de memória|Mem_ctrl_RTL.png|600 px| Quartus Light}}


{{fig|4.7|FSM do controlador de memória|Mem_ctrl_FSM.png|1000 px| Quartus Light}}
;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:


* Simulação do controlador de memória.
; Declaração do componente:
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".
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.


{{fig|4.8|Simulação do controlador de memoria - diferença entre a saída Moore e saída Mealy|FSM_Moore_Mealy_SIM.png|1000 px|}}
component_declaration ::= 
    component identifier [ is ] 
        [ generic_clause ] 
        [ port_clause ] 
    end component [ identifier ] ;


{{fig|4.9|Simulação de escritas, leituras simples e leitura em burst no controlador de memoria |FSM_Mem_SIM.png|1000 px|}}
Exemplo de declaração do componente:


;Encontro 32 (6 fev.)
*Circuito detector de borda
<syntaxhighlight lang=vhdl>
<syntaxhighlight lang=vhdl>
library ieee;
component MeuComponente is
use ieee.std_logic_1164.all;
    generic (
entity edge_detector1 is
        WIDTH : natural := 4
  port(
    )
      clk, reset: in std_logic;
    port (
      strobe: in std_logic;
        clk   : in  std_logic;
      p1: out std_logic
        reset : in std_logic;
  );
        data  : in std_logic_vector(7 downto 0);
end edge_detector1;
        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:


architecture moore_arch of edge_detector1 is
<syntaxhighlight lang=vhdl>
  type state_type is (zero, up, one);
Instancia2: MeuComponente
  signal state_reg, state_next: state_type;
    generic map (
begin
        8
  -- state register
    )
  process(clk,reset)
    port map (
  begin
        clk_signal,
      if (reset='1') then
        reset_signal,
        state_reg <= zero;
        input_data,
      elsif (clk'event and clk='1') then
        output_valid
        state_reg <= state_next;
    );
      end if;
</syntaxhighlight>
  end process;
 
  -- next-state logic
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.
  process(state_reg,strobe)
<syntaxhighlight lang=vhdl>
  begin
Instancia1: MeuComponente
      case state_reg is
    generic map (
        when zero=>
        WIDTH => 8
            if strobe= '1' then
    )
              state_next <= up;
    port map (
            else
        clk  => clk_signal,
              state_next <= zero;
        reset => reset_signal,
            end if;
        data  => input_data,
        when up=>
        valid => output_valid
            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>
</syntaxhighlight>
Fonte: RTL Hardware Desing, P. Chu.
No exemplo acima
{{fig|4.10|Simulação do detector de borda - implementação com saídas Moore|FSM_edge_detector_moore.png|1000 px|}}
*'''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.


Ao simular o detector de borda, percebe-se que o primeiro pulso (140ps) 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.
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.


<syntaxhighlight lang=vhdl>
;Arquivo da Entidade (Componente):
library ieee;
Um arquivo que define uma entidade (componente) deve conter:
use ieee.std_logic_1164.all;
*A declaração da entidade, que define as entradas e saídas do módulo.
entity edge_detector2 is
*A arquitetura, que contém a lógica do componente (ou uma descrição de como ele é implementado).
  port(
Exemplo de Arquivo para o Componente:
      clk, reset: in std_logic;
<syntaxhighlight lang=vhdl>
      strobe: in std_logic;
-- Arquivo: MeuComponente.vhd
      p2: out std_logic
library IEEE;
  );
use IEEE.STD_LOGIC_1164.ALL;
end edge_detector2;
 
-- 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;


architecture mealy_arch of edge_detector2 is
-- Declaração da arquitetura
  type state_type is (zero, one);
architecture Behavioral of MeuComponente is
  signal state_reg, state_next: state_type;
begin
begin
  -- state register
    -- Implementação da lógica do componente
  process(clk,reset)
    process(clk, reset)
  begin
    begin
      if (reset='1') then
        if reset = '1' then
        state_reg <= zero;
            valid <= '0';
      elsif (clk'event and clk='1') then
        elsif rising_edge(clk) then
        state_reg <= state_next;
            if data = "11111111" then
      end if;
                valid <= '1';
  end process;
  -- next-state logic
  process(state_reg,strobe)
  begin
      case state_reg is
        when zero=>
            if strobe= '1' then
              state_next <= one;
             else
             else
              state_next <= zero;
                valid <= '0';
             end if;
             end if;
        when one =>
        end if;
            if strobe= '1' then
    end process;
              state_next <= one;
end Behavioral;
            else
</syntaxhighlight>
              state_next <= zero;
Neste exemplo:
            end if;
*Entidade: Define as portas (clk, reset, data, valid).
      end case;
*Arquitetura: Implementa a lógica funcional do componente.
  end process;
;Arquivo do Top Level:
  -- Mealy output logic
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).
  p2 <= '1' when (state_reg=zero) and (strobe='1') else
        '0';
end mealy_arch;
</syntaxhighlight>
Fonte: RTL Hardware Desing, P. Chu.
{{fig|4.11|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 (140ps) 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.
Exemplo de Arquivo Top Level:
<syntaxhighlight lang=vhdl>
-- Arquivo: TopLevel.vhd


{{collapse bottom}}
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


===Unidade 5 - Metodologia RT (Register Transfer)===
-- 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;


{{collapse top | expand=true | Unidade 5 - Metodologia RT (Register Transfer)}}
-- Declaração da arquitetura do Top Level
A fonte principal dessa unidade é o capítulo 11 e 12 do livro "RTL Hardware Desing, P. Chu.".  É recomendado que os alunos leiam estes capítulos e usem como fonte de consulta.
architecture Structural of TopLevel is
;Encontro 33 (11 fev.)
    -- Sinais internos para conexão
*Ver [https://drive.google.com/file/d/1-w9S39oHsx70K4Gom3i-y1WfQPyvv10d/view?usp=drive_link capítulo 11] slide 1 a 30
    signal clk_signal  : std_logic;
*Introdução (exemplo de algoritmo de soma de 4 números, divisão inteira do resultado por 8.
    signal reset_signal : std_logic;
*Visão geral do FSMD
    signal input_data  : std_logic_vector(7 downto 0);
{{fig|4.12|Diagrama de blocos básico de uma FSMD |FSMD_block_diagram.png|800 px| RTL Hardware Desing, P. Chu}}
    signal output_valid : std_logic;


;Encontro 34 (13 fev.)
    -- Declaração do componente
*Implemente em VHDL o [https://drive.google.com/file/d/1f7DqWL9390nTGgXUVdd01CaSAJX-UxOC/view?usp=drive_link Listing 11.1 do livro do CHU]
    component MeuComponente is
{{fig|4.13|Diagrama ASMD do algoritmo multiplicador L11.1 |ASMD_mult_sum.png|300 px| RTL Hardware Desing, P. Chu}}
        port (
*Simulação essa FSMD, verificando o funcionamento da FSM através da simulação no MODELSIM. Teste com multiplicações menores (2 x 31 = 62); (31 x 2 = 62)  e maiores (9 x 31 = 279) (31 x 9 = 279).
            clk  : in  std_logic;
:*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.
            reset : in  std_logic;
:* 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.  Verifique também a versão 11.4.
            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;


;Encontro 35 (18 fev.)
    -- Instanciação do componente
*Implementação de um multiplicador por deslocamento de bits e somas sequenciais
    Instancia1: MeuComponente
*Implemente em VHDL o [https://drive.google.com/file/d/1f7DqWL9390nTGgXUVdd01CaSAJX-UxOC/view?usp=drive_link Listing 11.7  do livro do CHU]
        port map (
{{fig|4.14|Diagrama ASMD do algoritmo multiplicador L11.7 e 11.8 |ASMD_mult_shift_sum.png|300 px| RTL Hardware Desing, P. Chu}}
            clk  => clk_signal,
*Análise de tempo e desempenho do FSMD
            reset => reset_signal,
            data => input_data,
            valid => output_valid
        );


*Implementação de um multiplicador por somas sucessivas em dataflow (a + a + a + ...)
    -- Conectando o sinal interno à saída global
*Implementação de um multiplicador pelo bloco multiplicador  (a x b)
    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:


;Encontro 36 a 39 (20, 22, 25, 27 fev.)
Compilação:
*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]
*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.


;Encontro 40 (6 mar.)
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).
*Atividade de recuperação para alunos com conceito inferior a 6.
*Os demais alunos foram dispensados


<!--
A forma de lidar com isso depende se a porta é de entrada ou saída:
;Encontro 36 (20 ago.)
;Para uma Porta de Entrada Não Utilizada
*Circuito gerador de pulso (Implementação em lógica regular, em FSM, em FSMD)
As portas de entrada devem receber um valor, mesmo que não sejam usadas na lógica. Nesse caso, você pode:
{{fig|4.14|Diagrama ASMD do algoritmo do gerador de pulso|ASMD_pulse_generator.png|600 px| RTL Hardware Desing, P. Chu}}
Você pode conectar a porta a um literal (como '0', '1' ou "000...").
*Circuito para cálculo do máximo divisor comum (gcd)
{{fig|4.15|Diagrama ASMD do algoritmo do GCD|ASMD_gcd.png|600 px| RTL Hardware Desing, P. Chu}}


;Encontro 37 (23 ago.)
Exemplo:
*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] .
<syntaxhighlight lang=vhdl>
- GCD é descrito em 4.5.2. The Greatest Common Divisor), pag 346 do PDF
Instancia1: MeuComponente
- Algorithm E (Original Euclidean algorithm). pag 349 do PDF.
    port map (
        clk  => clk,
        reset => reset,
        data  => (others => '0'), -- Porta de entrada não utilizada
        valid => valid_signal
    );
</syntaxhighlight>


- 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. 
No exemplo acima, a entrada data foi conectada a (others => '0'), indicando que todos os bits do vetor serão definidos como 0.
- 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
;Para uma Porta de Saída Não Utilizada:
Q1.QAR, Q1-RTL.PNG, Q1-TM.PNG, Q1-SIM.PNG e o relatório
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'''.


Os arquivos tb_XXX.do e wave.do devem ser enviados dentro do QAR
Exemplo:


Pontuação
<syntaxhighlight lang=vhdl>
*7 pontos - pelo relatório e projeto com os  resultados dos algoritmos gcd slow e fast.
Instancia3: MeuComponente
*3 pontos - pelo relatório e projeto com os resultados do "Original Euclidean algorithm" em dataflow ou RT metodology
    port map (
-->
        clk  => clk,
{{collapse bottom}}
        reset => reset,
<!--
        data => data_signal,
;Encontro 38 (27 ago.)
        valid => open -- Porta de saída não utilizada
*Avaliação de Recuperação R12.   
    );
:1) Desenvolver um projeto de circuito sequencial [hierárquico] ou FSM ou FSMD.
</syntaxhighlight>
:2) Realizar e registrar todas as etapas de análise e síntese, verificar elementos lógicos, frequência máxima, e eventualmente o tempo de processamento.  
O '''open''' informa que a saída valid não será usada e evita que o compilador gere erros.
:3) Obter diagramas RTL, technology map, escrever corretamente os arquivos de script, com o sinal wave formatado adequadamente.   
{{collapse bottom}}  
:4) Enviar os arquivos necessários no .qar que permitam reproduzir os resultados obtidos.
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 timerCONTAR, 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.


==Avaliações==
<syntaxhighlight lang=vhdl>
Durante o semestre serão realizadas 4 avaliações.  As avaliações devem  ser enviadas pela plataforma Moodle com os arquivos solicitados.
entity timer_seg is
;Data das avaliações:
    generic (DEZENA : natural :=5; UNIDADE : natural := 9; FCLK := 5); -- para simulaçao
*A1 - : AE3 - Projeto de uma FSM para controle semafórico
port (
*A2 - : AE4 - Projeto de uma FSMD
CLK50MHZ, RESET : in std_logic;
*A3 - : Média ponderada de AE1 e AE2
CONTAR      : std_logic;
*R - Recuperação de A1 a A2 : Novo prazo para entrega das AE3 e AE4.
ZERAR        : std_logic;
*[[Folha de consulta de VHDL]]
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;


== Atividade relâmpago (AR) ==
architecture ifsc of top_level is
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.
begin


*Insira restrições de atraso máximo para o compilador utilizando o Synopsys Design Constraints File
end architecture;
*Modifique a técnica utilizada pelo Quartus na otimização em em Optimization Technique por default está selecionado [x] Balanced (Normal flow) .
</syntaxhighlight>
:*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.
{{fig|5.17|RTL timer_sec | RTL_timer_sec.png| 800 px |}}
:*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.  
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 |}}


;Entregas:
{{fig|5.20|Simulação do conta_bcd| SIM_conta_bcd.png| 800 px |}}
*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:
{{fig|5.21|Simulação do bcd2ssd (Catodo Comum)| SIM_bcd2ssdCC.png| 800 px |}}
*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===
{{fig|5.22|Simulação do bcd2ssd (Anodo Comum)| SIM_bcd2ssdAC.png| 800 px |}}
; 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:
*Ver funcionamento do [[Display de 7 segmentos]]
* 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:
;Encontro 13  (5 abr.)
* [[Restringir a frequencia máxima de clock no Quartus II]]
* Carry-Ripple Adder (FOR-LOOP) (Ex 6.4) - apenas analisar.
* [[Como obter o Fmax do projeto no Quartus]]
:* 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'''


===AR3 - Desafio: contador bcd===
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.
; 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.
<syntaxhighlight lang=vhdl>
*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.
library ieee;
*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.
use ieee.std_logic_1164.all;


;Entregas:
entity carry_ripple_adder is
* Na simulação e na análise considere a contagem de 00 a 23, definindo os parâmetros D = 2 e U = 3.
generic (N : integer := 3);
* Envie o QAR com o projeto compilado e configurado com o '''maior valor de Fmax''' que você conseguiu.
port (
* Envie a captura da imagem mostrando o relatório com essa frequência.
a, b : std_logic_vector (N-1 downto 0);
* 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.
cin  : std_logic;
* Envie no texto online os seguintes dados:
s    : out std_logic_vector (N-1 downto 0);
:1) Qual versão foi implentada (v1, v2 ou v3).
cout : out std_logic
:2) O maior valor de Fmax obtido.
);
:3) Qual o número de elementos lógicos utilizados no projeto.
end entity;


;Bonificação na A1:
architecture estrutural_sequencial_v1 of carry_ripple_adder is
*1,0 - para o(a) primeiro estudante que enviar o contador funcionando (versão 1, 2 ou 3)
begin
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 1)
-- Uso de um codigo sequencial para geracao de um circuito combinacional
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 2)
process (a, b, cin) is
*1,0 - para o(a) estudante que obtiver o maior valor de Fmax  (versão 3)
variable c : std_logic;
-->
begin
 
c := cin;
== Atividade extra-classe (AE) ==
for i in 0 to N-1 loop
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.
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;


===AE1 -  Conhecendo os dispositivos lógicos programáveis===
architecture estrutural_concorrente_v1 of carry_ripple_adder is
{{collapse top | bg=lightyellow | AE1 -  Conhecendo os dispositivos lógicos programáveis}}
signal c : std_logic_vector(N downto 0);
;Objetivos:
begin
*Conhecer o Quartus Prime e as características dos dispositivos lógicos programáveis
-- Uso de um codigo concorrente para geracao de um circuito combinacional
*Analisar os tempos de propagação em um circuito combinacional
c(0) <= cin;
*Alterar configurações do compilador
l1: for i in 0 to N-1 generate
*Fazer a simulação funcional e temporal de um circuito combinacional.
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>


;Atividades:
{{fig|5.17|RTL do carry_ripple_adder de 3 bits | RTL_carry_ripple_adder3.png| 800 px |}}
*'''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 desse dispositivo.
<!--
:*Capture as telas solicitadas e depois utilize-as no relatório da atividade.
;Encontro 17 (12 nov.):
:*Anote o tempo utilizado para cada uma das etapas do processo de compilação.
* Uso de type para definir novos tipos de dados.  Exemplo de integer_vector
:*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.
 
:*Anote algum erro ('''Error''') ou alertas ('''Warnings''') que o Quartus II indicar no painel de mensagens '''[Messages]'''
*Instrução '''WAIT''': WAIT UNTIL, WAIT FOR (simulação apenas), WAIT ON (não implementada no Quartus II).  
:*Ao final salve o projeto em um arquivo QAR (sugestão PJ1.QAR)
 
<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'''.


*'''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.
* 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.
:*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.
:*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]]
:* versão 1 - contagem crescente.
:*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.18|RTL do contador BCD 00 a 99 | RTL_countBCD00-99.png| 800 px |}}
:*Capture as telas mostradas no roteiro e depois utilize-as no relatório da atividade.
{{fig|5.19|Simulação do contador BCD 00 a 99 | MODELSIM_countBCD00-99.png| 800 px |}}
:*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 de um dos projetos '''CI74161''' ou do '''cálculo da distância de Hamming'''
;DESAFIO:
:*Capture as telas que mostram o circuito funcionando e depois utilize-as no relatório da atividade.
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.


;Entregas:
;Encontro 19 e 20 (19 e 21 nov.):
#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.
;Encontro 21 (26 nov.):
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
 
{{collapse bottom}}
* 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.
===AE2 - Laboratório de programação de FPGA - Relógio HHMMSS===
:* Utilize um segundo circuito para obter um clock de 0,1 Hz
{{collapse top | bg=lightyellow | AE2 - Laboratório de programação de FPGA - Relógio HHMMSS}}
:* 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:
;Objetivos:
*Desenvolver sistemas utilizando componentes já desenvolvidos.
*Desenvolver sistemas utilizando componentes já desenvolvidos.
Linha 2 242: Linha 3 597:


===AE3 -  Projeto de uma FSM para controle semafórico===
===AE3 -  Projeto de uma FSM para controle semafórico===
{{collapse top | expand=true | bg=lightyellow | AE3 -  Projeto de uma FSM para controle semafórico}}
{{collapse top | bg=lightyellow | AE3 -  Projeto de uma FSM para controle semafórico}}
;Objetivos:
;Objetivos:
*Aplicar o conhecimento de FSM no projeto de um controle semafórico.
*Aplicar o conhecimento de FSM no projeto de um controle semafórico.
Linha 2 292: Linha 3 647:


===AE4 - Comparação de Hardware projetado por FSMD e Dataflow===
===AE4 - Comparação de Hardware projetado por FSMD e Dataflow===
{{collapse top | expand=true | bg=lightyellow | 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:
;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 FSMD para multiplicação de dois números.
Linha 2 302: Linha 3 657:


;Atividades:
;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 do livro do CHU.  
*'''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.
::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
:*Realize a '''Analyses e Synthesis''', '''Fitter''' e '''Timing Analysis''' de cada versão
Linha 2 310: Linha 3 665:


*'''PASSO 2 -''' Análise da variação do número de bits
*'''PASSO 2 -''' Análise da variação do número de bits
:*Altere o código do CHU para que funcione para um número genérico 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.
::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');
  constant zeros : std_logic_vector(N-1 downto 0) := (others => '0');
Linha 2 360: Linha 3 715:
#Sugira qual circuito utilizaria em diferentes situações e quais jamais utilizaria.   
#Sugira qual circuito utilizaria em diferentes situações e quais jamais utilizaria.   
#Escreva uma boa conclusão sobre isso
#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}}
<!--
*'''PASSO 3 - ''' Código da FIFO
:*Use as duas entities anteriores para construir a FIFO. 
:*Fazer  a Análise e Síntese desse código
:*Observar o RTL
:*Verificar o número de elementos lógicos usados, variando o número de endereços da FIFO entre 16 e 1024 endereços, testando as 3 versões de controlador.
:*Fazer Timing Analysis e anotar as FMax de cada versão.
:*Fazer a simulação funcional com 16 endereços, faça com que os sinais de FULL e EMPTY sejam alterados com a escrita e leitura.
:*Escreva na FIFO números crescentes, e observe a diferença na localização dos mesmos na memória para contador binário e LFSR.
*'''PASSO 4 - ''' Preparação do relatório
:*Capture as telas dos RTL, e as simulações que mostram o circuito funcionando e utilize-as no relatório da atividade.
*'''DICAS sobre LFSR'''
:*Os bits que devem ser usados no LFSR podem ser encontrados como entrada dos XOR estão indicados como Taps (ou Feedback polynomial) na seção [https://en.wikipedia.org/wiki/Linear-feedback_shift_register Example polynomials for maximal LFSRs]da Wikipedia. Por exemplo para 4 bits, é indicado "Taps 1100"
:*Neste outro documento  [https://docs.amd.com/v/u/en-US/xapp052 Efficient Shift Registers, LFSR Counters, and Long Pseudo-Random Sequence Generators], na '''Tabela 3: Taps for Maximum-Length LFSR Counters''', tem a indicação dos bits a serem usados no XOR. Note que o primeiro bit é 1 e não 0.  Por exemplo para 4 bits, é indicado "XNOR from 4,3.
{{fig|AE2.1|LFSR de 4 bits (Tap 1100) (XNOR from 4,3) |LFSR_4bits.png|800 px|https://media.cheggcdn.com/media/e15/e1599ae9-9038-4483-a36f-7b4a60d40dc4/phpvL7umw}}
;Entregas:
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar a FIFO.
#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.
#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.
#A entrega será feita através do Moodle da disciplina.  Observe o prazo de entrega.
Linha 2 444: Linha 3 773:
==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